文章编译器(C语言实现)
设计内容:
- (1)具有图形菜单界面;
- (2)查找,替换(等长,不等长),插入(插串,文本块的插入)、块移动(行块,列块移动),删除;
- (3)可正确存盘、取盘;
- (4)正确显示总行数。(行数不少于5行,每行字符数不少于80个字符)
设计要求: - (1) 符合课题要求,实现相应功能;
- (2) 要求界面友好美观,操作方便易行;
- (3) 注意程序的实用性、安全性。
#include <stdio.h>
#include <iostream>
#include <string.h>
#include <stdlib.h>
#include <conio.h>
#define MAXNUM 80
#define OVERFLOW -1
#define OK 1
#define MAXLIST 100
#define ERROR 0
typedef int Status;
//定义结构体
typedef struct Line{
char text[MAXNUM];//本行文本
Status num;//行号
Status length;//列的长度
struct Line *next;//指向下一行
struct Line *prior;//指向上一行
}Line,*LineList;
//函数声明
void Meanu(void);//菜单
void CreatText(LineList &head);//创建
Status PrintList(LineList head);//显示
void SaveFile(LineList head);//保存到文件中
void LoadFile(LineList &head);//从文件中读取
Status FindText(LineList head);//查找文本内容
Status PrintLine(LineList head);//遍历行
Status DeleteLine(LineList &head);//删除行
Status DeleteString(LineList &head);//删除串
Status InsertLine(LineList &head);//插入行
Status InserString(LineList &head);//插入串
Status ReplaceEQ(LineList &head);//替换等长
Status ReplaceLT(LineList &head);//替换不等长
Status MoveMenu();//移动子菜单
Status InsertEmpty(LineList &head,Status num);//向上移动空行
Status EmptyLine(LineList &head,Status num); //向下移动行
Status EmptyRow(LineList &head,Status num); //向右移动列
Status EmptyString(LineList &head,Status num);//向左移动列
//-------------------------------------------------------------函数开始-------------------------------------------------------------------------
//菜单函数开始
void Meanu(void)
{
system("cls");
printf("\t\t\t=============[文本编译器]==============\n");
printf("\t\t\t= [1].创建文本 =\n");
printf("\t\t\t= [2].查找文本 =\n");
printf("\t\t\t= [3].插入文本 =\n");
printf("\t\t\t= [4].移动文本 =\n");
printf("\t\t\t= [5].删除文本 =\n");
printf("\t\t\t= [6].存盘 =\n");
printf("\t\t\t= [7].取盘 =\n");
printf("\t\t\t= [8].显示文本 =\n");
printf("\t\t\t= [9].替换文本 =\n");
printf("\t\t\t= [0].退出 =\n");
printf("\t\t\t=======================================\n");
printf("\n");
printf("请选择你需要的功能:\n");
}
//菜单函数结束
//创建函数开始
void CreatText(LineList &head)
{
LineList temp;
Status i,j;
char ch;
head=(LineList)malloc(sizeof(Line));
head->next=NULL;
head->prior=NULL;
temp=(LineList)malloc(sizeof(Line));
head->next=temp;
temp->prior=head;
printf("输入文本内容:以#号结束");
for(i=0;i<MAXLIST;i++)
{
for(j=0;j<MAXNUM;j++)
{
scanf("%c",&ch);
// 因为scanf把'\r'干掉了所以只剩下一个\n
if(ch=='\n'||ch=='#')
{
break;
}
temp->text[j]=ch;
}
temp->length=j;
temp->num=i+1;
if(ch=='#')
{
temp->next=NULL;
break;
}
temp->next=(LineList)malloc(sizeof(Line));
temp->next->prior=temp;
temp=temp->next;
}
printf("创建成功!!!\n");
}
//创建函数结束
//显示函数开始
Status PrintList(LineList head)
{
Status i=0;
LineList p=head->next;
while(p!=NULL)
{
printf("行号:%3d 长度:%2d ",p->num,p->length);
for(i=0;i<p->length;i++)
{
printf("%c",p->text[i]);
}
printf("\n");
p=p->next;
}
return OK;
}
//显示函数结束
//保存文件函数开始
void SaveFile(LineList head)
{
LineList temp=head->next;
char *p;
FILE *fp;
Status i=0;
if((fp=fopen("D://data.text","w"))==NULL)
{
printf("打开失败!!!\n");
exit(0);
}
while(temp!=NULL)
{
p=temp->text;
i=0;
while(*p)
{
i++;
//去掉最后的回车
if(i==81)
{
break;
}
putc(*p++,fp);
}
putc('\n',fp);
temp=temp->next;
}
fclose(fp);
printf("保存成功!!!\n");
}
//保存文件函数结束
//读取文件函数开始
void LoadFile(LineList &head)
{
FILE *fp;
char ch;
Status num=1,i=0;
LineList p,q;
head=(LineList)malloc(sizeof(Line));
head->prior=NULL;
head->next=NULL;
if((fp=fopen("D://data.text","r"))==NULL)
{
printf("文件不存在!!!\n");
exit(0);
}
p=(LineList)malloc(sizeof(Line));
head->next=p;
p->prior=head;
while((ch=fgetc(fp))!=EOF)
{
fseek(fp,-1,1);//因为已经读取了一个字符所以要重新定位到前一个字符
i=0;
while((ch=fgetc(fp))!='\n')//以行读取
{
p->text[i]=ch;
i++;
}
p->length=i;
p->text[i]='\0';//每行的结束标志为\0
p->num=num++;
q=(LineList)malloc(sizeof(Line));
if(q==NULL)
{
printf("申请内存失败!!!\n");
exit(0);
}
p->next=q;
q->prior=p;
p=q;
}
p->next=NULL;
fclose(fp);
if(p->num==0)
{
p->prior->next=NULL;
}
printf("读取成功!!!\n");
}
//读取文件函数结束
//查找文本开始
Status FindText(LineList head)
{
Status i=0,j=0,length=0,num=0;
char *q;
char a[80],b[80];
LineList p=head->next;
printf("请输入你想要查找的字符串:\n");
gets(a);
length=strlen(a);
q=a;
while(p!=NULL)
{
i=0;
while(i<=p->length-length)
{
strncpy(b,&p->text[i],length);
b[length]='\0';
if(strcmp(b,q)==0)
{
num++;
printf("行号:%d 列号:%d\n",p->num,i);
}
i++;
}
p=p->next;
}
return OK;;
}
//查找文本结束
//显示一行函数开始
Status PrintLine(LineList head)
{
LineList p=head->next;
int num,j=0;
printf("请输入你想要查找的一行的行号:\n");
scanf("%d",&num);
while(p!=NULL)
{
if(p->num==num)
{
puts(p->text);
j=1;
}
p=p->next;
}
if(j==0)
{
printf("对不起,没有这一行!!!\n");
}
return OK;
}
//显示一行函数结束
//删除函数开始
Status DeleteLine(LineList &head)
{
LineList p=head->next,q;
int num,j=0;
printf("请输入你想要删除的行号:\n");
scanf("%d",&num);
while(p!=NULL)
{
if(p->num==num)
{
q=p->next;
p->next->prior=p->prior;
p->prior->next=p->next;
break;
}
p=p->next;
}
printf("删除成功!!!\n");
while(q!=NULL)
{
q->num--;
q=q->next;
}
return OK;
}
//删除函数结束
//删除字符串的函数开始
Status DeleteString(LineList &head)
{
char a[80],b[80];
LineList p=head->next;
char *q;
Status i=0,j=0,length=0,len=0,k=0,m=0;
q=a;
printf("请输入想要删除的字符串:\n");
gets(a);
length=strlen(a);
while(p!=NULL)
{
i=0;
memset(b,0,sizeof(b));
while(i<=p->length-length)
{
strncpy(b,&p->text[i],length);
b[length]='\0';
if(strcmp(b,q)==0)
{
len=1;
j=i+length;
m=i;
while(j<p->length)
{
p->text[m]=p->text[j];
m++;
j++;
}
k=1;
}
i++;
if(k==1)
{
p->length=p->length-length;
k=0;
}
}
p=p->next;
}
return len;
}
//删除字符串的函数结束
//插入行文本开始
Status InsertLine(LineList &head)
{
Status i=0,num=0,length=0;
char ch;
LineList p=head->next,q,s;
printf("请输入你想要插入的行号:");
scanf("%d",&num);
q=(LineList)malloc(sizeof(Line));
q->num=num;
q->length=0;
printf("请输入你想要插入的文本内容:以#号结束");
fflush(stdin);//清除缓冲流
for(i=0;i<MAXNUM;i++)
{
scanf("%c",&ch);
if(ch=='#'||ch=='\n')
{
break;
}
q->text[i]=ch;
}
q->length=i;
while(p!=NULL)
{
if(p->num==num)
{
q->next=p;
q->prior=p->prior;
p->prior->next=q;
p->prior=q;
break;
}
p=p->next;
}
while(p!=NULL)
{
p->num=(p->num+1);
p=p->next;
}
return OK;
}
//插入行文本结束
//插入串开始
Status InserString(LineList &head)
{
LineList p=head->next;
Status i=0,j=0,row=0,k=0,length=0,num=0;
char a[80];
char *q;
printf("请输入想要插入的行号和列号(用空格隔开):\n");
scanf("%d%d",&num,&row);
fflush(stdin);
printf("请输入想要插入的串:\n");
gets(a);
q=a;
length=strlen(a);
while(p!=NULL)
{
if(p->num==num)
{
if(p->length+length>MAXNUM)
{
printf("不能插入!!!\n");
return ERROR;
}
else
{
for(i=p->length+length-1,j=p->length-1;i>=row;i--,j--)
{
p->text[i]=p->text[j];
}
for(i=row;k<length;i++,k++)
{
p->text[i]=a[k];
}
p->length=p->length+length;
}
}
p=p->next;
}
return OK;
}
//插入串结束
//替换等长的开始
Status ReplaceEQ(LineList &head)
{
LineList p;
Status i=0,j=0,length=0,k=0;
p=head->next;
char a[80],b[80];
printf("请输入替换的字符串:\n");
gets(a);
printf("请输入被替换的字符串:\n");
gets(b);
length=strlen(b);
while(p!=NULL)
{
i=0;
while(i<=p->length-length)
{
if(strncmp(b,&p->text[i],length)==0)
{
k=i;
for(j=0;j<length;j++)
{
p->text[k]=a[j];
k++;
}
}
else
{
}
i++;
}
p=p->next;
}
return OK;
}
//替换等长结束
//替换不等长的串开始
Status ReplaceLT(LineList &head)
{
LineList p=head->next;
Status i=0,j=0,k=0,m=0,n=0,la,lb,max;
char a[80],b[80],c[80];
printf("请输入替换的串:\n");
gets(a);
la=strlen(a);
printf("请输入被替换的串:\n");
gets(b);
lb=strlen(b);
memset(c,0,sizeof(c));
while(p!=NULL)
{
i=0;
j=0;
// 计算出一行中有几个这样的字符
while(i<p->length)
{
if((strncmp(b,&p->text[i],lb))==0)
{
k++;
i=i+lb;
}
else
{
i=i+1;
}
}
if(k==0)
{
p=p->next;
continue;
}
while(j<p->length)
{
if(la*k+p->length-lb*k>MAXNUM)
{
printf("不能完全完成替换!!!\n");
}
else
{
if((strncmp(b,&p->text[j],lb))==0)
{
if(j>=m)
{
if(m<j)
{
m=m;//位置不必变化
}
else
{
m=j;
}
}
strncpy(&c[m],a,la);
m=m+la;
j=j+lb;
}
if((strncmp(b,&p->text[j],lb))!=0)
{
strcpy(&c[m],&p->text[j]);
j=j+1;
m++;
}
}
}
p->length=p->length+k*la-k*lb;
k=0;
m=0;
for(n=0;n<p->length;n++)
{
p->text[n]=c[n];
}
memset(c,0,sizeof(c));
p=p->next;
}
return OK;
}
//替换不等长的串结束
//块的移动函数开始
Status MoveMenu()
{
Status c=0;
printf("1.向上移动\n");
printf("2.向下移动\n");
printf("3.向左移动\n");
printf("4.向右移动\n");
do
{
printf("请输入你想哪个方向移动:\n");
scanf("%d",&c);
}while(c<1&&c>=5);
return c;
}
Status InsertEmpty(LineList &head,Status num)
{
char ch;
LineList p=head->next,q,s;
q=(LineList)malloc(sizeof(Line));
q->num=num;
q->length=0;
fflush(stdin);//清除缓冲流
q->text[0]='\n';
while(p!=NULL)
{
if(p->num==num)
{
q->next=p;
q->prior=p->prior;
p->prior->next=q;
p->prior=q;
break;
}
p=p->next;
}
while(p!=NULL)
{
p->num=(p->num+1);
p=p->next;
}
return OK;
}
Status EmptyLine(LineList &head,Status num)
{
LineList p=head->next,q;
while(p!=NULL)
{
if(p->num==num)
{
if(p->next==NULL)
{
p->prior->next=NULL;
p=NULL;
}
else
{
q=p->next;
p->prior->next=p->next;
p->next->prior=p->prior;
}
free(p);
break;
}
p=p->next;
}
while(q!=NULL)
{
if(q==NULL)
{
break;
}
q->num--;
q=q->next;
}
return OK;
}
Status EmptyRow(LineList &head,Status num)
{
LineList p=head->next;
Status i=0,j=0,length=1;
char a[80];
a[0]=' ';
a[1]='\0';
if(num>80)
{
return ERROR;
}
while(p!=NULL)
{
if(p->length==80)
{
p=p->next;
continue;//如果是80不能移动
}
for(i=p->length+length-1,j=p->length-1;i>=num;i--,j--)
{
p->text[i]=p->text[j];
}
p->text[num]=' ';
if(p->length==80)
{
p->length=80;
}
else
{
p->length=p->length+length;
}
a[0]=' ';
a[1]='\0';
p=p->next;
}
return OK;
}
Status EmptyString(LineList &head,Status num)
{
LineList p=head->next;
Status i=0;
if(num==0)
{
return ERROR;
}
while(p!=NULL)
{
if(p->length==0)
{
p=p->next;
continue;
}
for(i=num;i<p->length;i++)
{
p->text[i]=p->text[i+1];
}
p->length--;
p=p->next;
}
return OK;
}
//块的移动函数结束
//-------------------------------------------------------------函数结束-------------------------------------------------------------
//-----------------------------------------------------------主函数开始-------------------------------------------------------------
int main(void)
{
LineList T;
Status i=0,n=0,t=0,num=0;
Meanu();
scanf("%d",&i);
while(i!=10)
{
Meanu();
switch(i)
{
case 1: fflush(stdin);CreatText(T);break;
case 2: fflush(stdin);FindText(T);break;
case 3: printf("1.插入文本块2.插入串\n");
t=0;
scanf("%d",&n);
if(n==1)
{
t=InsertLine(T);
}
else
{
t=InserString(T);
};
if(t==1)
{
printf("插入成功!!!\n");
}
break;
case 4: n=0;n=MoveMenu();
switch(n)
{
case 1:printf("请输入你想要移动的行号:\n");
scanf("%d",&num);
t=0;
t=EmptyLine(T,num);
if(t==1)
{
printf("移动成功!!!\n");
}
else
{
printf("移动失败!!!\n");
}
break;
case 2:printf("请输入你想要移动的行号:\n");
scanf("%d",&num);
t=0;
t=InsertEmpty(T,num);
if(t==1)
{
printf("移动成功!!!\n");
}
else
{
printf("移动失败!!!\n");
}
break;
case 3:
printf("请输入你想要移动的列号:\n");
scanf("%d",&num);
t=0;
t=EmptyString(T,num);
if(t==1)
{
printf("移动成功!!!\n");
}
else
{
printf("移动失败!!!\n");
}
break;
case 4:
printf("请输入你想要移动的列号:\n");
scanf("%d",&num);
t=0;
t=EmptyRow(T,num);
if(t==1)
{
printf("移动成功!!!\n");
}
else
{
printf("移动失败!!!\n");
}
break;
}
break;
case 5:printf("1.删除文本块2.删除串\n");
scanf("%d",&n);
t=0;
fflush(stdin);
if(n==1)
{
t=DeleteLine(T);
}
else
{
t=DeleteString(T);
}
if(t==1)
{
printf("删除成功!!!\n");
}
else
{
printf("没有删除!!!\n");
}
break;
case 6: SaveFile(T);break;
case 7: LoadFile(T);break;
case 8: printf("1.显示所有内容2.显示一行\n");
scanf("%d",&n);
t=0;
if(n==1)
{
t=PrintList(T);
}
else
{
t=PrintLine(T);
}
if(t==1)
{
printf("成功显示!!!\n");
}
break;
case 9: printf("1.替换等长2.替换不等长:\n");
scanf("%d",&n);
t=0;
fflush(stdin);
if(n==1)
{
t=ReplaceEQ(T);
}
else
{
t=ReplaceLT(T);
}
if(t==1)
{
printf("替换成功!!!\n");
}
else
{
printf("没有替换成功!!!");
}
break;
default:exit(0);
}
scanf("%d",&i);
}
return 0;
}
别废话,拿你代码给我看。