Chinaunix首页 | 论坛 | 博客
  • 博客访问: 1496449
  • 博文数量: 148
  • 博客积分: 2234
  • 博客等级: 大尉
  • 技术积分: 3225
  • 用 户 组: 普通用户
  • 注册时间: 2012-05-17 21:34
个人简介

未来很长。

文章存档

2017年(7)

2016年(4)

2015年(1)

2014年(6)

2013年(31)

2012年(99)

分类: C/C++

2012-05-19 12:11:26


点击(此处)折叠或打开

  1. #include<stdio.h>
  2. #include<malloc.h>
  3. #include<conio.h>
  4. #include<string.h>
  5. #include<stdlib.h>
  6. #define ERR_NOMEMORY -1
  7. #define ERR_INVALIDPARAM -2
  8. #define ERR_OVERFLLOW -3
  9. #define ERR_ILLEGALINDEX -4
  10. #define ERR_EMPTYRESULT -5
  11. #define STRING_MAXSIZE 256
  12. #define STRING_MAXLINE 2
  13. typedef struct HeapString{//用堆存储法

  14.     char *elems;
  15.     int length;
  16. }HeapString;

  17. int num=0;

  18. int IniString(HeapString *str,char *buffer)
  19. {
  20.     int i=0;

  21.     if(!buffer) return ERR_INVALIDPARAM;

  22.     if(!str) return ERR_INVALIDPARAM;

  23.     while(*(buffer+i)!='\0') i++;//求这一行的字符串长度
  24.     // str->elems=(char *)malloc(i*sizeof(char));

  25.     str->elems=(char *)malloc((i+1)*sizeof(char));

  26.     if(!str->elems) return ERR_NOMEMORY;

  27.     if(i>STRING_MAXSIZE-1)
  28.     {
  29.         printf("输入的字符个数超过了256 !\n");
  30.         return 0;
  31.     }

  32.     str->length=i;

  33.     for(i=0;i<str->length;i++)

  34.         str->elems[i]=buffer[i];

  35.     str->elems[i]='\0';

  36.     return 1;
  37. }
  38. void Input(char buffers[],HeapString line[])
  39. {
  40.         int i=0;
  41.         printf("请输入文本内容 ,每段以'#'结束 : \n");
  42.         while(1)
  43.         {
  44.             gets(buffers);
  45.             
  46.             if(buffers[0]=='#') break;

  47.             IniString(&line[num++],buffers);

  48.             if(num>STRING_MAXLINE-1)
  49.             {
  50.                 break;
  51.             }

  52.             
  53.         }
  54.     
  55. }


  56. void Delete(HeapString *str)
  57. {
  58.     int choice;
  59.     printf("请输入要删除的行 :\n");
  60.     scanf("%d",&choice);
  61.     if(choice>0&&choice<=num)
  62.     {
  63.         free(str[--choice].elems);
  64.         while(choice<num-1)
  65.         {
  66.             str[choice].elems=str[choice+1].elems;
  67.             str[choice].length=str[choice+1].length;
  68.             choice++;
  69.         }

  70.     }
  71.     num--;
  72.     printf("已成功删除该行文本\n");
  73.     
  74. }
  75. void DeleteAll(HeapString *str)
  76. {
  77.     int choice;
  78.     int i;
  79.     printf("确定要删除该文本吗? (y/n):");
  80.     printf("%c\n",(char)(choice=getch()));
  81.     if(choice!=89&&choice!=121) return ;
  82.     for(i=0;i<num;i++)
  83.         free(str[i].elems);
  84.     num=0;
  85.     printf("已成功删除所有内容 \n");
  86. }
  87. void KMPGetNext(char *T,int n2,int nextval[])
  88. {
  89.     int j=1,k=0;
  90.     nextval[0]=-1;
  91.     while(j<n2)
  92.     {
  93.         if(k==0||T[k]==T[j])
  94.         {
  95.             nextval[j]=T[k]==T[j]?nextval[k]:k;
  96.             j++,k++;
  97.         }
  98.         else
  99.             k=nextval[k];
  100.     }
  101. }
  102. int KMPIndex(char *S,int n1,char *T,int n2)
  103. {
  104.     int i=0,j=0;
  105.     int *next=(int *)malloc(n2*sizeof(int));
  106.     if(!next) return ERR_NOMEMORY ;
  107.     KMPGetNext(T,n2,next);
  108.     while(i<n1&&j<n2)
  109.     {
  110.         if(j==-1||S[i]==T[j])
  111.             i++,j++;
  112.         else
  113.             j=next[j];
  114.     }
  115.     free(next);
  116.     return (j>=n2?i-n2:-1);
  117. }
  118. void FindSubString(HeapString *str,char *buffers)
  119. {
  120.     HeapString sub;
  121.     int i,k;
  122.     printf("请输入要查找的字串: ");
  123.     gets(buffers);
  124.     IniString(&sub,buffers);
  125.     printf("查找结果为: \n");
  126.     for(i=0;i<num;i++)
  127.     {
  128.         k=KMPIndex(str[i].elems,str[i].length,sub.elems,sub.length);
  129.         if(k>=0)
  130.             printf("要查找的字串在第%d行位置为%d处出现 :\n",i+1,k+1);
  131.     }
  132.     free(sub.elems);
  133. }
  134. int StringInsert(HeapString *S,int n,HeapString *T)
  135. {
  136.     int j=n-1;

  137.     int k,len;
  138.     char *S1=(char *)malloc(STRING_MAXSIZE*sizeof(char));
  139.     
  140.     
  141.     strcpy(S1,S->elems);
  142.     S1[S->length]='\0';

  143.     if(!S||!T) return ERR_ILLEGALINDEX;

  144.     if(n<=0) return ERR_ILLEGALINDEX;
  145.     len=S->length+T->length;

  146.     S->elems=(char *)malloc(STRING_MAXSIZE*sizeof(char));
  147.         if(!S->elems) return ERR_NOMEMORY;

  148.     strcpy(S->elems,S1);
  149.     if(n==S->length)
  150.     {

  151.         for(j=0;j<T->length;j++)
  152.         {
  153.             S->elems[j+S->length]=T->elems[j];
  154.         }
  155.         S->elems[j+S->length]='\0';
  156.         free(S1);
  157.         return 1;
  158.     }

  159.     for(k=S->length-1;k>=j;k--)
  160.         S->elems[k+T->length]=S->elems[k];
  161.     for(k=0;k<T->length;k++)
  162.         S->elems[k+j]=T->elems[k];
  163.         S->length=len;
  164.     
  165.         S->elems[S->length]='\0';
  166.         free(S1);
  167.     return 0;
  168. }
  169. void InsertsubString(HeapString *str,char *buffer)
  170. {
  171.     HeapString sub;
  172.     int i,k;
  173.     printf("请输入要插入的子串 :\n");
  174.     flushall();
  175.     gets(buffer);
  176.     IniString(&sub,buffer);
  177.     printf("请输入要插入的行和列 (row,col):\n");
  178.     scanf("%d,%d",&i,&k);
  179.     if(i<=0||k>STRING_MAXSIZE)
  180.         printf("插入的子串:输入的列号无效:\n");
  181.     if(StringInsert(&str[i-1],k,&sub)>=0)
  182.         printf("插入子串成功:\n");
  183.     free(sub.elems);

  184. }
  185. int StrDelete(HeapString *S,int i,int k,int n)
  186. {
  187.     int j;
  188.     if(!S)
  189.     {
  190.         printf("Error !\n");
  191.         return 0;
  192.     }
  193.     for(j=k;j<S->length-n;j++)
  194.     {
  195.         S->elems[j]=S->elems[j+n];
  196.     }
  197.     S->elems[j]='\0';
  198.     return 1;

  199. }
  200. void DeletesubString(HeapString *str)
  201. {
  202.     int i,k,choice;
  203.     printf("请输入要删除的行和列(row,col): ");
  204.     scanf("%d,%d",&i,&k);
  205.     printf("请输入要删除的个数 :");
  206.     scanf("%d",&choice);
  207.     if(StrDelete(&str[i-1],i-1,k-1,choice))
  208.         printf("成功删除子串 :\n");
  209. }

  210. int main()
  211. {
  212.     char buffers[STRING_MAXSIZE];
  213.     HeapString line[STRING_MAXLINE];

  214.     int i;
  215.     int choice;

  216.     do{
  217.     
  218.         printf("\n 简单的\"记事本\" \n");
  219.         printf(" 1.输入文本 2.删除一行 3.删除文本 \n");
  220.         printf(" 4.查找子串 5.插入子串 6.删除子串 \n");
  221.         printf(" 7.显示文本 0.退出 \n");
  222.         printf("请输入您的选择 :%d\n",(choice=getch()-48));
  223.         switch(choice)
  224.         {
  225.          case 1:
  226.              Input(buffers,line);
  227.             break;
  228.          case 2:
  229.              Delete(line);
  230.              break;
  231.          case 3:
  232.              DeleteAll(line);
  233.              break;
  234.          case 4:
  235.              FindSubString(line,buffers);
  236.              break;
  237.          case 5:
  238.              InsertsubString(line,buffers);
  239.              break;
  240.          case 6:
  241.              DeletesubString(line);
  242.              break;

  243.          case 7:
  244.              for(i=0;i<num;i++)
  245.                  printf("行 %d:%s\n",i+1,line[i].elems);
  246.              if(num==0)
  247.                  printf(">内容为空 !\n");
  248.              break;
  249.         }
  250.     
  251.     }while(1);
  252.     return 0;
  253. }


刚开始在写完这个程序的时候,运行竟然出现这样的错误:

 断点调试发现前面都可以通过只要走到释放内存的free处,程序就会挂掉,后来发现是内存访问越界,针对程序而言是使用malloc申请的空间过小,编译器傻不拉叽的往前走,读写都可以正常得到结果,直到free的时候编译器才发现问题,于是就崩掉了,想一下那个条件是什么来着,while(*(buffer+i)!='\0')i++;//求这一行的字符串长度,但是我们知道字符串都是以0结尾的啊,但是当求到buffer[i]=='\0'时,竟然跳出了循环,所以所求的字符串长度就不够啊,所以你为一个字符串malloc空间的时候,就没地方存放他的那个结尾0,所以出现了内存错误。所以说只要把iniString时malloc的空间加大一个字节问题就解决了。
   由此我们可以看到malloc申请空间的时候一定要谨慎,编译器报出来的错误往往定位不到合适的位置,容易浪费大量的时间检查无关的地方,如果是用c++的new和delete组合就能减少这种问题的发生概

 

 

 

 

阅读(3777) | 评论(0) | 转发(1) |
给主人留下些什么吧!~~