当前位置:文档之家› 简易文本编辑器说明书

简易文本编辑器说明书

中北大学课程设计说明书学院、系:专业:班级:学生姓名:学号:设计题目:简易文本编辑器起迄日期: 2016年12月16日~2016年12月29日指导教师:日期: 2016年12月29日1 设计目的通过用户调查分析及实际需求,开发出一个文本编辑器,可以方便用户对文本进行编辑。

系统需要实现如下基本功能:(1)具有图形菜单界面;(2)查找,替换(等长,不等长),插入(插串,文本块的插入)、块移动(行块,列块移动),删除;(3)可正确存盘、取盘;(4)正确显示总行数。

2 任务概述要设计一简易的文本编辑器,要求有图形菜单界面,也就是菜单选择的界面,要实现的功能有对文本进行存盘,取盘,在某一个盘中新建一个TXT的文件,在里面输入内容,对这个文件进行取盘,显示出文本内容,并在显示的时候显示行数,具有对文本进行查找、替换、插入、移动、删除等功能。

为实现数据的有序存储,该编辑器应该用顺序表来存储输入的信息。

顺序表是数据结构中线性表的一种,它是用一块地址连续的存储空间依次存储线性表的元素。

其特点为:在顺序表上逻辑关系相邻的两个元素在物理位置上也相邻;在顺序表上可以随即存取表中的元素。

在编辑器的主界面中应有如下提示信息:⑴显示当前文本信息:从文件中读出文本,在某一个盘中创建一个文本文件,所以要读出来,显示到显示器上,并统计出行数。

⑵查找文本信息:因为在下面做插入,删除,移动之类的都需用到查找,在查找的时候,也要调用一个字符匹配模式的程序,来判断查找的内容是否符合所要查找的内容。

⑶删除文本信息:首先在数组中查找要删除的信息,查找的时候调用匹配模式的子函数,如果找到该信息,提示是否确认删除该信息,通过确认来删除信息,如果未找到要删除的信息,提示未找到该信息;⑷插入文本信息:首先调用字符匹配模式的子函数找到插入点,如果找到该插入点,提示输入插入信息,确认插入信息后,选择是否在这个位置插入,如果是的话执行插入,不是的话再往下查找下一个插入点。

⑸替换文本信息:首先在数组中查找要被替换的信息,如果找到该信息,提示输入要替换的信息内容,否则提示未找到要被替换的信息;⑹保存文本信息:在这里使用文件写入读出的功能,把你修改完的内容保存到你所建立的文本中。

⑺显示文本内容:读出文件中的所有字符,显示到显示器上。

⑻退出3 模块划分(1)系统主要包含主程序模块和其他操作模块。

其调用关系如图(一)所示。

图(一)(2)文本编辑器的运行流程图如图(二)所示。

图(二)(3)系统子模块及其功能设计:1.文件的打开:void open(char text[]);2.文件的保存:void save(char text[]);3.查找文本:void search(char text[],int l);4.字符的匹配:int strindex(char text[],char t[],int i2,int l);5.文本的输出:void output(char text[]);6.删除文本:void Delete(char p[],int l);7.插入文本:void insert(char text[],int l);8.替换文本:void Replace(int status);4 主要函数说明及其N-S图(1)对于文本内容的处理,查找部分仍是使用循环对已存储的文章进行匹配,判断需要查找的字符或者字符串是否与文章中某部分内容相同,在程序的执行中,先是进入的主函数,在主函数中调用了菜单函数,进行功能的选择,各个模块分为多个函数来实现。

在程序中,设置了几个全局变量,来记录文本的内容等信息:char text[MAX]=""; //文本编辑域char name[20]=""; //文件保存的位置int status=0; //显示是否保存过的状态int ntext; //文本编辑的位置(2)字符匹配在这个程序中要特别注意的是字符的匹配,因为查找、插入、替换都需要用到这一步设计。

在这里我设计了一个子模块来实现匹配:int strindex(char text[],char t[],int i2,int l) //查找要操作的数据的位置(模式匹配) {int i1=l,j=0;while (i1<ntext&&j<i2){if (text[i1]==t[j]) //继续匹配下一个字符{j++;i1++;} //主串和子串依次匹配下一个字符else //主串、子串指针回溯重新开始下一次匹配{i1=i1-j+1; //主串从下一个位置开始匹配j=0;} //子串从头开始匹配}if (j>=i2){return(i1-i2);} //返回匹配的第一个字符的下标elsereturn(-1); //模式匹配不成功}(3而且程序中用的顺序表存储的形式,在执行的时候考虑到在查找时,要显示是在第几行第几列的位置,但是程序并不是用二维数组来实现的,并不记录文本中每一个字符的行列号,所以如果直接一下子统计出来的话,就会出现行列号上的错误,所以在程序中使用了一下LOOP语句,来让程序一行一行的统计与显示。

当调用strindex(text,str1,t,l)函数时,得到返回值,如果a!=-1时,得到返回的是查找的字符串的第一字符的下标,l=a+t;t是字符的长度,hs,ls,分别记录行号与列号。

loop:a=strindex(text,str1,t,l);if (a!=-1){l=a+t;}int hs=1,ls=0;for (i=0;i<=a;i++){ls++;if (text[i]=='\n'){hs++;ls=0;}} if (a==-1){printf("查找到结尾没有找到\n输入【R】将重头查找;");l=0;fflush(stdin);pd=getchar();}else{printf("已经找到在第%d行第%d列,输入【R】继续查找下一处;",hs,ls);kk+=1;fflush(stdin);bd=getchar();if (bd=='R'||bd=='r')goto loop;}5(1)界面(2)打开已有文件(3)查找具体内容(4)删除内容(5)插入内容(6)替换内容(7)保存文件(8)退出6 课程设计心得通过这次的实训,对之前所学的C语言与数据结构都在加深一下印象,也把之前学得不是很熟悉的数据结构都做了一次回顾。

在程序中,我用到的数据结构是顺序表,顺序表是用一组地址连续的存储单元依次存储线性表的数据元素,这种表也称为顺序存储结构或顺序映像。

在程序调试的时候,也遇到了许多问题,最严重的问题,就是程序并不是用二维数组来实现的,在文件中的字符定位问题时,我用的是先找到第一行,再使用LOOP语句来使用循环,再做下一行的定位,这样在查找的时候就是一行一行的显示的,不会出现行数与列数统计上出错的问题。

有的时候做一个程序时,如果不会很好地使用一些特别深的方法的时候,那么可以换一种思考角度,就像上面的问题,用二维数组来实现虽然会很方便地进行行号列号地定位,但是在对后面的问题处理上就会又要涉及到别的处理方法,所以在这里可以换一种思维方式,用简单的方式来思考同一个问题,就会有不同的发现了。

附录:#include"stdio.h"#include"stdlib.h"#include"string.h"void open(char text[]);void save(char text[]);void search(char text[],int l);int strindex(char text[],char t[],int i2,int l); void output(char text[]);void Delete(char p[],int l);void insert(char text[],int l);void Replace(int status);void menu();#define MAX 10000char text[MAX]=""; //文本编辑域char name[20]=""; //文件保存的位置int status=0; //显示是否保存过的状态int ntext; //文本编辑的位置void open(char text[]) // 文件的打开{system("cls");FILE *fp;char pd,ch;char name[30];int i=0,ss=1;printf("输入A:确定打开文件 M:返回主菜单");fflush(stdin);pd=getchar();if (pd=='A'||pd=='a'){p rintf("请输入要打开文件名字(例如c:\\a.txt)");s canf("%s",name);w hile ((fp=fopen(name,"r"))==NULL){printf("\n打开文件失败,请重新输入要打开的文件名:");scanf("%s",name);}s ystem("cls");w hile(!feof(fp)){ch=fgetc(fp);if(ch=='\n') ss++;text[i++]=ch;}t ext[i]='\0';n text=i;f close(fp);p rintf("\n文件读取成功\n文件内容为\n");o utput(text);p rintf("有%d行",ss);}if (pd=='M'||pd=='m')menu();}void save(char text[]) //文件的保存{system("cls");FILE *fp;char pd;char tmp;int i;printf("\n输入【A】保存;\n");fflush(stdin);pd=getchar();if (!(pd=='A'||pd=='a')){m enu();}else{i f(name[20]==NULL){printf("\n请输入保存文件名(例如: c:\\a.txt):");scanf("%s",name);}w hile ((fp=fopen(name,"w+"))==NULL){printf("文件不存在,请重新输入文件名:");scanf("%s",name);}p rintf("\nA:确定;B:取消:");while(scanf("%c",&tmp)!=EOF){if (tmp=='A' || tmp=='a'){for(i=0;i<ntext;i++)fprintf(fp,"%c",text[i]);fclose(fp);status=1;printf("\n文件保存成功\n");break;}if (tmp=='B' || tmp=='b'){break;}}}}int strindex(char text[],char t[],int i2,int l) //查找要操作的数据的位置(模式匹配) {int i1=l,j=0;while (i1<ntext&&j<i2){i f (text[i1]==t[j]) //继续匹配下一个字符{j++;i1++;}//主串和子串依次匹配下一个字符e lse //主串、子串指针回溯重新开始下一次匹配i1=i1-j+1; //主串从下一个位置开始匹配j=0;}//子串从头开始匹配}if (j>=i2){r eturn(i1-i2);} //返回匹配的第一个字符的下标elser eturn(-1); //模式匹配不成功}void search(char text[],int l) //查找文本{system("cls");int i,t,a=-1,kk=0;char str1[20],bd,pd;printf("原文为:\n");output(text);printf("请输入您要查找的内容");scanf("%s",str1);printf("您查找的内容是:%s\n",str1);t=strlen(str1);loop:a=strindex(text,str1,t,l);if (a!=-1){l=a+t;}int hs=1,ls=0;for (i=0;i<=a;i++){l s++;i f (text[i]=='\n'){hs++;ls=0;}}if (a==-1){p rintf("查找到结尾没有找到\n输入【R】将重头查找;");l=0;f flush(stdin);p d=getchar();}else{p rintf("已经找到在第%d行第%d列,输入【R】继续查找下一处;",hs,ls);kk+=1;f flush(stdin);b d=getchar();if (bd=='R'||bd=='r')goto loop;}printf("一共找到了%d次",kk);if (pd=='R'||pd=='r'){l=0;search(text,l);}}void output(char text[]) //文本的输出{system("cls");printf("现在文本的内容为:\n");printf("%s\n",text);int hs=1,i;f or (i=0;i<ntext;i++){if (text[i]=='\n'){hs++;}}printf("\n文本共有%d行\n",hs);}void Delete(char p[],int l) //删除文本{int i,a=-1,t2=0;char x[20],px,pd,pdx,c;system("cls");printf("%s",p);printf("\n输入A执行查找删除内容");fflush(stdin);px=getchar();if (px=='a'||px=='A'){p rintf("\n输入您要删除的内容,以@结束:");f flush(stdin);w hile ((c=getchar())!='@'){if (c=='@'){break;}else{x[t2++]=c;continue;}}loop:a=strindex(p,x,t2,l);i nt hs=1,ls=0;f or (i=0;i<=a;i++){ls++;if (p[i]=='\n'){hs++; ls=0;}}i f (a==-1){printf("已查找结束,您要删除的内容不存在\n输入【R】重新输入要删除的内容; ");l=0;fflush(stdin);pdx=getchar();}e lse{printf("你要删除的内容在第%d行第%d列\n 输入【A】确定删除;输入【B】寻找下个词;",hs,ls);fflush(stdin);pd=getchar();l=t2+a;if (pd=='a'||pd=='A'){for(i=a;i<ntext;i++){p[i]=p[i+t2];}ntext=ntext-t2;printf("删除成功,删除后的内容为:\n%s\n",text);}else if (pd=='b'||pd=='B')goto loop;}i f(pdx=='r'||pdx=='R')Delete(text,l);}}void insert(char text[],int l) //向文本中插入内容{system("cls");int i=0,t=0,t2=0,a=-1,b;char cr[20]="",pd,x[500],c,d;printf("\n当前文本信息为:\n");printf("%s",text);printf("\n输入您要在哪个内容前插入,以@结束:");fflush(stdin);while ((c=getchar())!='@') //用一个数组接收要插入在哪个内容之前{i f (c=='@'){break;}e lse{cr[t++]=c;continue;}}loop:a=strindex(text,cr,t,l); //查找并返回要插入的位置点int hs=1,ls=0;for (b=0;b<a;b++){l s++;i f (text[b]=='\n'){hs++;ls=0;}}if (a==-1){p rintf("\n查找到结尾没有找到插入点,输入【R】查找其他;\n");l=0;f flush(stdin);d=getchar();f flush(stdin);}else{p rintf("\n您要插入的位置是第%d行,第%d列之前\n",hs,ls+1);p rintf("\n【A】.不是此位置向后继续找插入点\n【B】.在此位置插入\n按其他键返回菜单\n请选择:");f flush(stdin);p d=getchar();if (pd=='a'||pd=='A'){l=a+t;goto loop;}e lse if (pd=='b'||pd=='B'){printf("\n\n输入您要插入的内容,以@结束:");fflush(stdin);while ((c=getchar())!='@'){if (c=='@'){break;}else{x[t2++]=c;continue;}}for (i=ntext;i>=a;i--){text[i+t2]=text[i];}for (i=0;i<t2;i++){text[i+a]=x[i];}ntext=ntext+t2;printf("\n当前文本信息为:\n");for (i=0;i<=ntext-1;i++)printf("%c",text[i]);printf("\n文本插入成功\n");fflush(stdin);getchar();}}if (d=='r'||d=='R'){l=0;i nsert(text,l); }status=0;}void Replace(char p[],int l) //内容替换{int t=0,t1=0,i,a,b;char c,th[20],d,d1,bth[20];int i2;system("cls");printf("\n当前文本信息为:\n");for (i2=0;i2<=ntext-1;i2++)printf("%c",p[i2]);printf("\n输入要被替换的内容,以@结束:");fflush(stdin);while ((c=getchar())!='@') //t指替换前内容的长度{i f (c=='@'){break;}e lse{bth[t++]=c;continue;}}loop:a=strindex(p,bth,t,l); //查找要被替换的内容的位置int hs=1,ls=0;for (b=0;b<a;b++){l s++;i f (p[b]=='\n'){hs++;ls=0;}}if (a==-1){p rintf("\n查找到结尾没有找到要被替换的内容\n输入【R】查找其他内容\n");l=0;d=getchar();f flush(stdin); //用来清空输入缓存,以便不影响后面输入的东西}else{p rintf("\n\n已经找到要查找的数据在第%d行第%d列\n输入",hs,ls+1);p rintf("\n【A】继续向后查找相同内容\n输入其他键将进行替换操作\n请选择:");f flush(stdin);l=t+a;c har pd;p d=getchar();if (pd!='a'&&pd!='A'){p rintf("\n是否要替换该内容?\nA:替换给内容;其他键返回主菜单\n请选择:");f flush(stdin);d1=getchar();i f (d1=='a'||d1=='A'){printf("\n输入要替换的内容,以@结束:");fflush(stdin);while ((c=getchar())!='@') //t1指替换后的内容长度{if (c=='@'){break;}else{th[t1++]=c;continue;}}if (t==t1) //将要被替换的内容和替换后的内容进行长度比较{for (i=0;i<t1;i++)p[i+a]=th[i];}elseif (t>t1){for (i=0;i<t1;i++){p[i+a]=th[i];}for (i=a+t1;i<ntext;i++){p[i]=p[i+t-t1];}ntext=ntext+t1-t;}else{for (i=ntext;i>=a;i--){p[i+t1-t]=p[i];}for (i=0;i<t1;i++){p[i+a]=th[i];}ntext=ntext+t1-t;}}printf("替换成功");printf("\n当前文本信息为:\n");for (i2=0;i2<=ntext-1;i2++)printf("%c",p[i2]);getchar();status=0;}}elseg oto loop;}if(d=='r'||d=='R')Replace(text,l);}void menu(){system("cls");loop:system("cls");printf("\n");printf("*****************************************************\n"); printf("**** 欢迎使用简易文本编辑器 ****\n");printf("*****************************************************\n"); printf("********************\n");printf("1、打开文件\n");printf("2、查找\n");printf("3、删除\n");printf("4、插入\n");printf("5、替换\n");printf("6、保存\n");printf("7、显示内容\n");printf("8、退出 ****\n");printf("********************\n");printf("请选择(1~8):");char c;f flush(stdin);i f(c>='0'&&c<='9'){switch (c){case '1':open(text);break;case '2':search(text,0);break;case '3':Delete(text,0);break;case '4':insert(text,1);break;case '5':Replace(text,0);break;case '6':save(text);break;case '7':output(text);break;case '8':exit(0);default : break;}}e lse{printf("\n输入有误,请重新输入:");fflush(stdin);c=getchar();}system("pause");g oto loop;}int main(){menu();}。

相关主题