C语言实例解析精粹学习笔记——39(简单的文本编辑器)

实例说明:

  编辑一个简单的单行文本编辑器,编辑命令有以下几种:(E、Q、R、I、D)

只有自己在完全空白的情况下编写出来的程序,才是真正自己会的程序,现在所做的,不过是程序的搬运工,把书上的程序搬到网上,不过是添加了几句注释而已。

  1 #include <stdio.h>
  2 #include <stdlib.h>
  3 #include <string.h>
  4 
  5 #define MAXLEN  80            //所处理文本一行最大字符个数
  6 #define MAXLINE 200           //所处理文本最大行数
  7 
  8 char  buffer[MAXLEN];         //用来存储命令行输入的命令,以及命令所带的参数
  9 char  fname[120];             //用来存储所处理文件的文件名
 10 char  *lineptr[MAXLINE];      //行指针
 11 FILE  *fp;                    //文件指针
 12 void  edit(),replace(),insert(),delete(),quit(); //函数声明,具体的函数定义在后面
 13 char  comch[] = "EeRrIiDdQq";                    //命令符
 14 void(*comfun[])() = {edit,replace,insert,delete,quit};  //对应处理函数
 15 int   modified=0;                                //正文修改标志
 16 int   last;                                      //当前正文行数
 17 char  *chpt;                                     //输入命令行字符指针
 18 
 19 
 20 int main()
 21 {
 22     int j;
 23     last = 0;
 24 
 25     while(1)
 26     {
 27         printf("\nInput a command:[e,r,i,d,q].\n");
 28         gets(buffer);                                            //读入命令行
 29         for(chpt=buffer; *chpt==' '||*chpt=='\t'; chpt++);       //掠过空白符
 30         if(*chpt=='\0') continue;                                //空行重新输入
 31         for(j=0; comch[j]!='\0'&&comch[j]!=*chpt; j++);          //查找命令符对应的处理函数
 32         if(comch[j]=='\0') continue;                             //非法命令符
 33         chpt++;                                                  //掠过命令符,指向参数
 34         (*comfun[j/2])();                                        //执行对应的函数
 35         fprintf(stdout,"The text is :\n");
 36         for(j=0; j<last; j++)                                    //显示正文文本
 37             fputs(lineptr[j],stdout);
 38     }
 39     return 0;
 40 }
 41 
 42 //====================================================================================
 43 //函数名称:void quit()
 44 //函数功能:结束编辑
 45 //对应命令:q/Q
 46 //入口参数:无
 47 //出口参数:无
 48 //====================================================================================
 49 void quit()
 50 {
 51     int c;
 52     if(modified)                                                     //判断正文是否被修改
 53     {
 54         printf("Save?(y/n)");
 55         while(!(((c=getchar())>='a'&&c<='z')||(c>='A'&&c<='Z')));    //判断输入是否为合法字符
 56         if(c=='y'||c=='Y')
 57             save(fname);
 58     }
 59     for(c=0; c<last; c++)
 60         free(lineptr[c]);                                            //释放内存
 61     exit(0);
 62 }
 63 
 64 //====================================================================================
 65 //函数名称:void insert()
 66 //函数功能:将I/i命令后继的K行文本插入到原始正文第M行之后
 67 //入口参数:无
 68 //出口参数:无
 69 //命令格式:
 70 //I K M
 71 //K行正文
 72 //====================================================================================
 73 void insert()
 74 {
 75     int k,m,i;
 76     sscanf(chpt, "%d%d", &k, &m);
 77     if(m<0||m>last||last+k>=MAXLINE)                               //判断插入文本位置是否正确
 78     {
 79         printf("Error!\n");
 80         return;
 81     }
 82     for(i=last; i>m; i--)                                          //后继行向后移
 83         lineptr[i+k-1] = lineptr[i-1];
 84     for(i=0; i<k; i++)                                             //读入k行正文,并插入
 85     {
 86         fgets(buffer, MAXLEN, stdin);
 87         lineptr[m+i] = (char *)malloc(strlen(buffer)+1);
 88         strcpy(lineptr[m+1],buffer);
 89     }
 90     last += k;                                                    //修改正文行数
 91     modified = 1;                                                 //标明正文已被修改
 92 }
 93 
 94 //====================================================================================
 95 //函数名称:void delete()
 96 //函数功能:将原始正文中第M行至第N行的正文内容删去
 97 //入口参数:无
 98 //出口参数:无
 99 //命令格式:
100 //D M N
101 //====================================================================================
102 void delete()
103 {
104     int i,j,m,n;
105     sscanf(chpt, "%d%d", &m,&n);
106     if(m<=0||m>last||n<m)                                        //检查参数合理性
107     {
108         printf("Error!\n");
109         return;
110     }
111     if(n>last)
112         n = last;                                                //修正参数
113     for(i=m; i<=n; i++)                                          //删除正文
114         free(lineptr[i-1]);
115     for(i=m,j<n+1; j<=last; i++,j++)                             //将原文的N行之后的文本前移
116         lineptr[i-1] = lineptr[j-1];
117     last = i-1;
118     modified = 1;
119 }
120 
121 //====================================================================================
122 //函数名称:void replace()
123 //函数功能:用R命令后继的K行正文替代原始正文中的M行到N行的正文内容
124 //入口参数:无
125 //出口参数:无
126 //命令格式:
127 //R K M N
128 //K行正文
129 //====================================================================================
130 void replace()
131 {
132     int k,m,n,i,j;
133     sscanf(chpt,"%d%d%d",&k,&m,&n);                                  /* 读入参数 */
134     if(m<=0||m>last||n<m||last-(n-m+1)+k>=MAXLINE)                /* 检查参数合理性 */
135     {
136         printf("Error!\n");
137         return;
138     }
139     /* 先完成删除 */
140     if(n>last)
141         n=last;                                                     /* 修正参数 */
142     for(i=m;i<=n;i++)                                             /* 删除正文 */
143         free(lineptr[i-1]);
144     for(i=m,j=n+1;j<=last;i++,j++)                               //文本前移
145         lineptr[i-1]=lineptr[j-1];
146     last=i-1;
147     /* 以下完成插入 */
148     for(i=last;i>=m;i--)
149         lineptr[i+k-1]=lineptr[i-1];
150     for(i=0;i<k;i++)
151     {
152         fgets(buffer,MAXLEN,stdin);
153         lineptr[m+i-1]=(char *)malloc(strlen(buffer)+1);
154         strcpy(lineptr[m+i-1],buffer);
155     }
156     last+=k;    /* 修正正文行数 */
157     modified=1;    /* 正文被修改 */
158 }
159 
160 //====================================================================================
161 //函数名称:void save(char *fname)
162 //函数功能:用来保存文本
163 //入口参数:char *fname
164 //出口参数:无
165 //====================================================================================
166 void save(char *fname)    /* 保存文件 */
167 {
168     int i;
169     FILE *fp;
170     if((fp=fopen(fname,"w"))==NULL)
171     {
172         fprintf(stderr,"Can't open %s.\n",fname);
173         exit(1);
174     }
175     for(i=0;i<last;i++)
176     {
177         fputs(lineptr[i],fp);
178         free(lineptr[i]);
179     }
180     fclose(fp);
181 }
182 
183 //====================================================================================
184 //函数名称:void edit()
185 //函数功能:指定所要编辑的文本
186 //入口参数:无
187 //出口参数:无
188 //====================================================================================
189 void edit()    /* 编辑命令 */
190 {
191     int i;
192     FILE *fp;
193     i=sscanf(chpt,"%s",fname);    /* 读入文件名 */
194     if(i!=1)
195     {
196         printf("Enter file name.\n");
197         scanf("%s",fname);
198     }
199     if((fp=fopen(fname,"r"))==NULL) /* 读打开 */
200     {
201         fp=fopen(fname,"w");    /* 如不存在,则创建文件 */
202         fclose(fp);
203         fp=fopen(fname,"r");    /* 重新读打开 */
204     }
205     i=0;
206     while(fgets(buffer,MAXLEN,fp)==buffer)
207     {
208         lineptr[i]=(char *)malloc(strlen(buffer)+1);
209         strcpy(lineptr[i++],buffer);
210     }
211     fclose(fp);
212     last=i;
213 }

 

posted @ 2018-11-02 14:34  llccbb1  阅读(754)  评论(0编辑  收藏  举报