一个简单的文本编译器

花了几天,从没有思路到写完。因为是第一次写这种命令交互式的,所以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 }

下面给出运行结果:

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

有兴趣的同学可以改进!

时间: 2024-10-28 23:29:57

一个简单的文本编译器的相关文章

一个简单的文本聚类实现(python)

具体实现如下,使用python+结巴分词+scikit-learn实现一个简单的文本聚类得到会议室数据,直接从DBA线上数据库得到预约数据,如下所示,共有3列,分别是会议ID,会议标题和会议时间 因为是中文,因此要进行分词,使用结巴分词对会议标题进行分词并过滤停用词分词代码如下(jiebafenci.py) #encoding=utf-8 import sys import re import codecs import os import shutil import jieba import

【Qt5开发及实例】12、实现一个简单的文本编辑器1

showwidget.h /** * 书本:[Qt5开发及实例] * 功能:实现一个简单的文本编辑器 * 文件:showwidget.h * 时间:2015年1月18日10:03:21 * 作者:cutter_point */ #ifndef SHOWWIDGET_H #define SHOWWIDGET_H #include <QWidget> #include <QLabel> #include <QTextEdit> #include <QImage>

【Qt5开发及实例】16、实现一个简单的文本编辑器(over)

实现一个简单的文本编辑器 其他具体的代码基础看前面:http://blog.csdn.net/cutter_point/article/details/42839071 1.功能 这个程序又添加了文本编辑功能,什么加粗,斜体,下划线,字体设置,字号设置,文字排版,段落对齐功能. 2.代码全展示 头文件 showwidget.h /** * 书本:[Qt5开发及实例] * 功能:实现一个简单的文本编辑器 * 文件:showwidget.h * 时间:2015年1月18日10:03:21 * 作者:

练习题,使用多线程编写一个简单的文本处理工具

一. 练习题要求: 编写一个简单的文本处理工具,具备三个任务,一个接收用户输入,一个将用户输入的内容格式化成大写,一个将格式化后的结果存入文件 二. 分析: 三个任务,那就是三个线程.分别的输入,转换,写入,这3个线程.那么写入的输入,其他线程怎么取出?我们可以使用Queue队列,把用户输入的字符写入到队列中,然后再进行转换.转换完成后,再写入到另外一个队列中.等待最后写入文件三.实现 1 from threading import Thread 2 from multiprocessing i

编译原理实战入门:用 JavaScript 写一个简单的四则运算编译器(四)结语

四则运算编译器,虽然说功能很简单,只能编译四则运算表达式.但是编译原理前端部分几乎都有涉及,词法分析,语法分析,还有代码生成. 再复杂的编译器.再简单的编译器,功能上是差不多的,只是复杂的编译器实现上会更困难. 这个系列的文章是为了帮助你入门,在这个基础上再去看编译原理相关书籍,不至于打瞌睡. 如果你对编译原理很有兴趣,并且想更深一步的学习,在这里强烈推荐你看一本书--我心目中的神书--<计算机系统要素-从零开始构建现代计算机>. 这本书神在哪? 神在它通俗易懂,对小白足够友好,但又不过分肤浅

制作一个简单的文本框输入的网页

题目:制作一个简单的网页(包含一个文本框.一个按钮),在页面上输出用户在文本框输入的内容,要求用JavaScript获取文本框内容. 一.首先利用html在网页上制作表单,代码如下: **onclick事件:onclick 事件会在对象被点击时发生. 二.利用js获取输入信息,并将其输出: 相关知识: 1.给用户确认消息,真正实现交互,使用语句confirm();给用户提示信息,实现单向通信,使用语句alert(). 三.运行结果: 1.用浏览器打开结果如下: 2.输入文本框内容,点击[提交]:

【Qt5开发及实例】14、实现一个简单的文本编辑器3

实现文本编辑器的图片旋转功能 基础界面实现:http://blog.csdn.net/cutter_point/article/details/42839071 首先在原来的基础上添加槽函数: void ShowRotate90(); //旋转90度 void ShowRotate180(); //180度 void ShowRotate270(); //270度 函数连接: //实现图片的选择动作 //旋转90° rotate90Action = new QAction(QIcon(":/ro

【Qt5开发及实例】13、实现一个简单的文本编辑器2

接下来我们为这个项目添加图像的缩放功能: 添加一个槽函数: void ShowZoomIn(); //关于图片的缩放功能 添加相应的响应连接 connect(zoomInAction, SIGNAL(triggered()), this, SLOT(ShowZoomIn())); //进行图片放大 槽函数的实现: //实现图片的放大 void ImageProcessor::ShowZoomIn() { //首先判断是否有照片 if(img.isNull()) return; //没有照片,那就

【Qt5开发及实例】15、实现一个简单的文本编辑器4

实现图片的镜像功能 其他具体的代码基础看前面:http://blog.csdn.net/cutter_point/article/details/42839071 槽函数: void ShowMirrorVertical(); //垂直镜像 void ShowMirrorHorizontal(); //水平镜像 相应的响应连接 //实现图像镜像的动作 //纵向 mirrorVerticalAction = new QAction(QIcon("mirrorVertical.png"),