码迷,mamicode.com
首页 > 其他好文 > 详细

一个简单的文本编译器

时间:2015-02-03 14:42:55      阅读:103      评论:0      收藏:0      [点我收藏+]

标签:

花了几天,从没有思路到写完。因为是第一次写这种命令交互式的,所以bug会很多。

格式:E/e:指定要编辑的文件

   Q/q:结束编辑

   R/r(用r命令后继的k行正文代替原始正文中的m行到n行)

    R  k m n

     k行正文

   I/i(将i命令后继的k行正文插入到原始正文第m行之后)

    I k m

     k行正文

   D/d(将原始正文中的第m行到第n行的正文内容删除)

    D m n

这是我写的代码:

技术分享
  1 /* 实现简单的文本编辑器 */
  2 /* bug1:先按e,再按文件名,循环后ch还是等于‘\n‘ */
  3 /* bug2:插入函数中,要是正文的一行最后不是回车的话,则插入的第一行会在所插的那一行上面,没有分开 */
  4 #include <stdio.h>
  5 #include <stdlib.h>
  6 #include <string.h>
  7 
  8 #define    CHMAX    80    /* 一行最多80个字符 */
  9 #define    LINEMAX    200    /* 最多允许200行 */
 10 
 11 char command[] = "EeRrIiDdQq";    /* 可选择的命令 */
 12 char buffer[CHMAX];            /* 输入的缓冲区 */
 13 char *Line[LINEMAX];    /* 行指针,用来输入一行 */
 14 char *chpt;    /* 获取命令及参数的字符指针 */
 15 char filename[256];    /* 输入的文件名 */
 16 FILE *fp;    /* 用于输入到文件的文件指针 */
 17 int modified = 0;    /* 修改标志 */
 18 int last;    /* 文本的最后一行,没有内容 */
 19 void Edit(), Replace(), Insert(), Delete(), Quit();
 20 void (*comfunc[])() = {Edit, Replace, Insert, Delete, Quit};    /* 函数指针数组 */
 21 void call();
 22 
 23 int main(void)
 24 {
 25     call();
 26     return 0;
 27 }
 28 
 29 void call()
 30 {
 31     int    j = 0;
 32     char    ch;
 33     last = 0;
 34 
 35     while (1)
 36     {
 37         j = 0;
 38         printf("Input a command: [e,r,i,d,q]\n");
 39 
 40         /* bug1 */
 41         //ch = ‘ ‘;
 42         //fflush(stdin);
 43         while ((ch = fgetc(stdin)) != \n)        /* 输入命令 */
 44         {
 45             buffer[j] = ch;
 46             j++;
 47         }
 48         buffer[j] = \0;
 49         
 50         for (chpt = buffer; *chpt ==   || *chpt == \t; chpt++)    /* 跳过空白符 */
 51             ;
 52         
 53         if (*chpt == \0)
 54         {
 55             printf("Doesn‘t input any command\n");
 56             continue;
 57         }
 58     
 59         for (j = 0; command[j] != *chpt && command[j] != \0; j++)    /* 获取命令的序号 */
 60             if (command[j] == \0)
 61             {
 62                 printf("Cannot find command.\n");
 63                 continue;
 64             }
 65         chpt++;            /* 指向参数 */
 66         (*comfunc[j/2])();    /* 执行相应的函数 */
 67 
 68         printf("The text is:\n");
 69         for (j = 0; j < last; j++)    /* 输出text的内容 */
 70             fputs(Line[j], stdout);
 71     }
 72 
 73 }
 74 
 75 void Edit()
 76 {
 77     int    i;
 78     FILE    *fp_temp;    /* 临时的文件指针 */
 79 
 80     i = sscanf(chpt, "%s", filename);    /* sscnaf函数返回值是参数的个数,参数应当只有一个 */
 81 
 82     if (i != 1)    /* 没有输入文件名或者输入超过一个文件名 */
 83     {
 84         printf("not input filename or more than 1 file, please input filename again:\n");
 85         scanf(" %s", filename);
 86     }
 87 
 88     /* 打开指定文件,没有就创建新的文件 */
 89     if ((fp_temp = fopen(filename, "r")) == NULL)    /* 没有这个文件,则创建新的文件 */
 90     {
 91         if ((fp_temp = fopen(filename, "w")) == NULL)/*  创建新的文件 */
 92         {
 93             printf("Cannot create a new file");
 94             return;
 95         }
 96         fclose(fp_temp);
 97         if ((fp_temp = fopen(filename, "r")) == NULL)
 98         {
 99             printf("Cannot read");
100             return;
101         }
102     }
103                                                                                                                    
104     i = 0;
105     while ((fgets(buffer, CHMAX, fp_temp)) == buffer)    /* 不用担心buffer越界问题,因为接下来没有使用到buffer */
106     {
107         Line[i] = (char *)malloc((strlen(buffer)) + 1);
108         strcpy(Line[i], buffer);
109         i++;
110     }
111     last = i;    
112     
113     fclose(fp_temp);
114     modified = 1;    /* 已修改 */
115 }
116 
117 void Replace()
118 {
119     int    i, k, m, n;    /* 将k行正文替换到第m行和第n行中 */
120     
121     if (modified != 1)
122     {
123         printf("Did not open a file.\n");
124         return;
125     }
126 
127     i = sscanf(chpt, "%d%d%d", &k, &m, &n);
128     if (i != 3 || m < 0 || n < 0 || k < 0 || m > n || n > last || k > last)
129     {
130         printf("format error\n");
131         return;
132     }
133 
134     
135     if (k != (n-m+1))
136     {
137         printf("error number of lines replaced.\n");
138         return;
139     }
140 
141     /* 写k行正文 */
142     printf("Please input %d line words:\n", k);
143 
144     /* 替换 */
145     for (i = 0; i < k; i++)
146     {
147         free(Line[m+i-1]);
148         fgets(buffer, CHMAX, stdin);
149         Line[m+i-1] = (char *)malloc(strlen(buffer) + 1);
150         strcpy(Line[m+i-1], buffer);
151     }
152         
153     modified = 1;
154 }
155 
156 void Insert()
157 {
158     int    i, k, m;    /* 将k行正文插入到原始正文第m行之后 */
159     
160 
161     if (modified != 1)    /* Edit最后修改modified标志 */
162     {
163         printf("Did not open a file.\n");
164         return;
165     }
166     
167     i = sscanf(chpt, "%d%d", &k, &m);
168     
169     if (i != 2 || k < 0 || m < 0 || last + k >= LINEMAX)
170     {
171         printf("format error.\n");
172         return;
173     }
174 
175     /* 写k行正文 */
176     printf("Please input %d line words:\n", k);
177 
178     /* 先将原文的第m+1行开始都向后移k行 */
179     for (i = last-1; i > m-1; i--)
180     {    
181         Line[i+k] = Line[i];/* 向后移k行 */
182     }
183     
184     /* 再将中间的k行补上 */
185     for (i = 0; i < k; i++)
186     {
187         fgets(buffer, CHMAX, stdin);
188         Line[m+i] = (char *)malloc(strlen(buffer) + 1);
189         strcpy(Line[m+i], buffer);
190     }
191     
192     last += k;    /* 给原来的last增加k行 */
193     modified = 1;    /* 已修改 */
194 }
195 
196 void Delete()
197 {
198     int    i, j, m, n;    /* 删去原始正文的第m行到第n行内容 */
199 
200     if (modified != 1)
201     {
202         printf("Did not open a filen\n");
203         return;
204     }
205     
206     i = sscanf(chpt, "%d%d", &m, &n);
207     if (i != 2 || m < 0 || n < 0 || m >n || n > last)
208     {
209         printf("format error\n");
210         return;
211     }
212 
213     /* 先删去,再移位 */
214     for (i = 0; i < (n-m+1); i++)
215         free(Line[m+i-1]);
216     for(i = n, j = 0; i < last; i++, j++)
217         Line[m+j-1] = Line[i];
218     last -= (n-m+1);
219 
220     modified = 1;
221 }
222 
223 void Quit()
224 {
225     int    i;
226     char    flag;
227     FILE    *fp_temp;
228 
229     printf("Save? y/n:");    
230     scanf(" %c", &flag);
231 
232     if (flag == Y || flag == y)
233     {
234         if ((fp_temp = fopen(filename, "w")) == NULL)
235         {
236             printf("Cannot open a file");
237             exit(1);
238         }
239         for (i = 0; i < last; i++)
240             fputs(Line[i], fp_temp);
241         printf("save successfully!\n");
242     }
243     else
244     ;
245     exit(0);
246 
247 }
View Code

 

下面给出运行结果:

 技术分享

 技术分享

ps:最好都是每一行都会有回车键,因为fgets函数是指定字符数的。具体看代码就应该知道了。

有兴趣的同学可以改进!

一个简单的文本编译器

标签:

原文地址:http://www.cnblogs.com/fusae-blog/p/4269652.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!