首页 > 代码库 > 一个简单的文本编译器
一个简单的文本编译器
花了几天,从没有思路到写完。因为是第一次写这种命令交互式的,所以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 else244 ;245 exit(0);246 247 }
下面给出运行结果:
ps:最好都是每一行都会有回车键,因为fgets函数是指定字符数的。具体看代码就应该知道了。
有兴趣的同学可以改进!
一个简单的文本编译器
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。