参照Windows的记事本等类似的文本编辑器,使用串的技术设计一个功能简单的文本编辑器。
(1)要求从文件系统中打开文本文件(例如文件名为ok.txt,位于当前执行程序的目录下);
(2) 文本文件中每行最多不超过80个字符,共N行(N>=1);
(3)信息读取后,要求存储结构使用链表和串,建立以串为结点单元的单链表,每行对应单链表的每个串结点;
(4)实现信息显示功能,将字符串按行显示在屏幕上;
(5)可以进行字符串的查找,并显示找到的字符串的位置(行、列);
(6)可以进行字符串的替换,注意替换后该行是否发生变化;
(7)可以指定插入位置后,进行字符串的插入,注意插入后该行是否发生变化;
(8)可以删除指定的字符串,注意删除后该行是否发生变化;
(9)可以将编辑后的内容存入文件 ;
(10)使用菜单模式,将各功能与数字序号结合,供用户选择;
【特别注意】可以自行添加设计其他功能,或以其他形式完成上述任务,创意无限,精彩无限。
#include<iostream>
#include<stdio.h>
#include<cstring>
#include<ctype.h>
#include<stdlib.h>
#define MAX_LEN 80
#define NOT_FOUND -1
#include<windows.h>
using namespace std;
typedef struct line
{
char text[81];
int num;///行号
struct line *next;
struct line *prior;
} txtline;
int lnum;///列号
txtline *start; /// 指向表中第一行的指针
txtline *last; /// 指向表中最后一行的指针
void Message();
txtline *find(int linenum);///查找指定行是否存在 刘
void patchup(int n, int inch);///对当前行以后的每行的行号加1或减一 孟
void delete_text(int linenum);///删除一行文字 张
void list();///显示全部内容 张
void save();///保存文件 何
void load();///打开文件,初始化线索表 何
void insert(char str[],int linenum,int position);///插入文字到一行的中间 孟
void printline(int linenum);///打印一行文字 张
void deletestr(int linenum,int position,int length);///删除一个字符串 张
int findstr(char *to_find);///查找字符串 刘
int menu_select(); ///孟
int menu_select_insert(); ///显示插入菜单 何
int menu_select_delete(); ///显示删除菜单 何
int menu_select_print(); ///显示打印菜单 何
int menu_select_move(); ///显示移动菜单 何
void enter(int linenum); ///插入一行文字 孟
void enter_empty(int linenum); ///插入一个空白行 孟
///创建双向列表
txtline* CreateDlinkList(txtline *p); ///何
///移动函数
void Moveback(txtline *info,char rext[]);///孟
void MoveForward(txtline *info);///孟
int main() ///全体成员
{
char str[MAX_LEN];
int choice = -1;
int linenum = 1;
int number = 0;
start = NULL;
last = NULL;
Message();
load();///载入文件
system("pause");
system("cls");
do
{
choice = menu_select();
switch(choice)
{
case 0:
txtline *p;
p=new txtline;
start=CreateDlinkList(p);
system("pause");
system("cls");
break;
case 1:
///执行插入操作
system("cls");
choice = menu_select_insert();
switch(choice)
{
case 1:
///插入一行
cout<<"\t行号:";
cin>>linenum;
enter(linenum);
system("pause");
system("cls");
break;
case 2:
///插入一个字符串
cout<<"输入插入位置的行号:"<<endl;
cin>>linenum;
cout<<"输入插入位置的列号:"<<endl;
cin>>number;
cout<<"要插入的字符串:"<<endl;
cin>>str;
insert(str,linenum,number);
system("pause");
system("cls");
break;
case 3:
system("pause");
system("cls");
break;///退出
}
break;
case 2:
///执行删除操作
system("cls");
choice = menu_select_delete();
switch(choice)
{
case 1:
///指定一行
cout<<"\t行号:";
cin>>linenum;
delete_text(linenum);
system("pause");
system("cls");
break;
case 2:
///删除指定的字符串
cout<<"要删除的字符串:"<<endl;
cin>>str;
number = findstr(str);
if(number == NOT_FOUND)
cout<<"没有找到"<<endl;
else
deletestr(lnum,number,strlen(str));
system("pause");
system("cls");
break;
case 3:
system("pause");
system("cls");
break;///退出
}
break;
case 3:
///显示功能
system("cls");
choice = menu_select_print();
switch(choice)
{
case 1: ///显示一行
cout<<"\t行号:"<<endl;
cin>>linenum;
printline(linenum);
system("pause");
system("cls");
break;
case 2: ///显示全部
list();
system("pause");
system("cls");
break;
case 3:
system("pause");
system("cls");
break;
}
break;
case 4: ///执行查找功能
system("cls");
cout<<"输入要查找的字符串:"<<endl;
cin>>str;
number = findstr(str);
if(number == NOT_FOUND)
cout<<"没有找到"<<endl;
else
cout<<"要查找的字符串所在行号"<<lnum<<" 列号:"<<number + 1<<endl;
system("pause");
system("cls");
break;
case 5:
///替换
system("cls");
cout<<"输入要被替换的字符串:"<<endl;
cin>>str;
number = findstr(str);
if(number == NOT_FOUND)
cout<<"没有找到"<<endl;
else
{
deletestr(lnum,number,strlen(str));
cout<<"要替换的字符串: ";
cin>>str;
insert(str,lnum,number+1);
cout<<"替换成功"<<endl;
}
system("pause");
system("cls");
break;
case 6:
///移动
system("cls");
choice = menu_select_move();
switch(choice)
{
case 1:///下
cout<<"输入要移动的字符所在行号:"<<endl;
cin>>linenum;
enter_empty(linenum);
system("pause");
system("cls");
break;
case 2:///上
cout<<"输入要移动的字符所在行号:"<<endl;
cin>>linenum;
delete_text(linenum-1);
system("pause");
system("cls");
break;
case 3:///右 一 lie
cout<<"输入要移动的字符串所在的行号:"<<endl;
cin>>linenum;
cout<<"输入要移动的字符串所在的列号:"<<endl;
cin>>number;
str[0] = ' ';
str[1] = '\0';
insert(str, linenum, number);
system("pause");
system("cls");
break;
case 4:
///左 1 列
cout<<"输入要移动的字符串所在行号:"<<endl;
cin>>linenum;
cout<<"输入要移动的字符串所在列号:"<<endl;
cin>>number;
if (number <= 0)
cout<<"该列不存在"<<endl;
else
deletestr(linenum, number - 2, 1);
system("pause");
system("cls");
break;
case 5:
system("pause");
system("cls"); //退出移动
break;
}
break;
case 7:
//执行存盘功能
save();
system("pause");
system("cls");
break;
case 8:
load();
system("pause");
system("cls"); //执行读入文件功能
break;
case 9://执行退出功能
system("cls");
cout<<"真的要退出吗 是输入y(Y),否则输入n(N)"<<endl;
char ch;
cin>>ch;
if(ch=='y'||ch=='Y')
{
cout<<"好吧,下次见"<<endl;
exit(0);
}
else
system("cls");
break;
}
}
while(1);
return 0;
}
void Message() ///弹出框
{
int i=MessageBox(NULL,
"欢迎使用文本编译器程序 ! \n\
本程序开发人员:xxx,xx,xxx,xxx",
"文本编译器",MB_OK);
return ;
}
///创建双向列表
txtline* CreateDlinkList(txtline *p)
{
txtline *head = p;
string str;
getchar();///消除回车键
cout<<"请输入文本:"<<endl;
getline(cin,str);
//system("pause");
long len = str.length();
int i = 0,k=1;
while(i<=len)
{
if(i%80==0&&i!=0)
{
p->text[80]='\0';
p->num=k++;
p->next = new txtline;
p->next->prior = p;
p = p->next;
}
p->text[i%80] = str[i];
i++;
}
p->text[80]='\0';
p->num=k++;
p->next = NULL;
last = p;
cout<<"创建成功"<<endl;
return head;
}
int menu_select() ///显示主菜单
{
int c;
cout<<"\t*************************************"<<endl;
cout<<"\t*\t\t0.创建\t\t *"<<endl;
cout<<"\t*\t\t1.插入\t\t *"<<endl;
cout<<"\t*\t\t2.删除\t\t *"<<endl;
cout<<"\t*\t\t3.显示\t\t *"<<endl;
cout<<"\t*\t\t4.查找\t\t *"<<endl;
cout<<"\t*\t\t5.替换\t\t *"<<endl;
cout<<"\t*\t\t6.移动\t\t *"<<endl;
cout<<"\t*\t\t7.文件存盘\t *"<<endl;
cout<<"\t*\t\t8.装入文件\t *"<<endl;
cout<<"\t*\t\t9.退出\t\t *"<<endl;
cout<<"\t*************************************"<<endl;
do
{
cout<<"\n\n\t\t请按数字选择:";
cin>>c;
}
while(c<0||c>9);
return c;
}
int menu_select_insert() ///显示插入菜单
{
int c;
cout<<"\n\t\t1.插入一行文字\n";
cout<<"\t\t2.插入一段文字\n";
cout<<"\t\t3.返回上级菜单\n";
do
{
cout<<"\n\n\t\t请按数字选择:";
cin>>c;
}
while(c<1||c>3);
return c;
}
int menu_select_delete() ///显示删除菜单
{
int c;
cout<<"\n\t\t1.删除一行文字\n";
cout<<"\t\t2.删除一段文字\n";
cout<<"\t\t3.返回上级菜单\n";
do
{
cout<<"\n\n\t\t请按数字选择:";
cin>>c;
}
while(c<1||c>3);
return c;
}
int menu_select_print() ///显示打印菜单
{
int c;
cout<<"\n\t\t1.显示一行\n";
cout<<"\t\t2.全部显示\n";
cout<<"\t\t3.返回上级菜单\n";
do
{
cout<<"\n\n\t\t请按数字选择:";
cin>>c;
}
while(c<1||c>3);
return c;
}
int menu_select_move() ///显示移动菜单
{
int c;
cout<<"\n\t\t1.向下移动一行\n";
cout<<"\t\t2.向上移动一行\n";
cout<<"\t\t3.向右移动一列\n";
cout<<"\t\t4.向左移动一列\n";
cout<<"\t\t5.返回上级菜单\n";
do
{
cout<<"\n\n\t\t请按数字选择:";
cin>>c;
}
while(c<1||c>5);
return c;
}
void enter(int linenum) ///插入一行文字
{
txtline *info,*q,*p;
p = start;
q = NULL;
while(p && p->num != linenum)
{
q = p;
p = p->next;
}
if(p == NULL && (q->num + 1) != linenum)
{
cout<<"输入的行号不存在";
}
else
{
info = new txtline;
cout<<"输入要输入的字符串:";
scanf("%s",info->text);
info->num = linenum;
if(linenum == 1) ///第一行
{
info->next=p;
p->prior=info;
info->prior=NULL;
start = info;
}
else if(q->num+1 != linenum)///最后一行
{
q->next = info;
info->prior = q;
info->next = NULL;
}
else
{
q->next = info;
info->next= p;
p->prior=info;
info->prior=q;
}
while(p) ///如果不是插入在最后一行,插入行后面的行号都加1
{
p->num++;
p=p->next;
}
cout<<"插入成功"<<endl;
}
}
void enter_empty(int linenum) ///插入一个空白行
{
txtline *info,*p;
info = new txtline;
if(!info)
{
cout<<"\t! 内存不够!"<<endl;
exit(0);
}
info->text[0] = ' ';
info->text[1] = '\0';
info->num = linenum;
if(find(linenum))
{
p = start;
if(linenum == 1)
{
info->next=p;
p->prior=info;
info->prior=NULL;
start = info;
}
else
{
while(p->next->num != linenum)
p=p->next;
info->next = p->next;
p->next->prior = info;
p->next =info;
info->prior = p;
}
patchup(linenum,1);
cout<<"\t移动成功"<<endl;
}
else
cout<<"该行不存在"<<endl;
}
void patchup(int n, int inch)///对当前行以后的每行的行号加1或减一
{
txtline *i;
i = find(n);
i = i->next;
while(i)
{
i->num+=inch;
i=i->next;
}
}
void MoveBack(txtline *info,char rext[])
{
txtline *p = info;
char rext1[MAX_LEN],rext2[MAX_LEN];
int len = strlen(info->text),len_str = strlen(rext);
while(len==MAX_LEN)
{
strcpy(rext1,&info->text[len-len_str]);
strncpy(rext2,info->text,len-len_str);
strcpy(info->text,rext);
strcat(info->text,rext2);
strcpy(rext,rext1);
info->text[MAX_LEN]='\0';
info = info->next;
len = strlen(info->text);
}
if(len+len_str>MAX_LEN)
{
strcpy(rext1,&info->text[MAX_LEN-len_str]);
strncpy(rext2,info->text,MAX_LEN-len_str);
strcpy(info->text,rext);
strcat(info->text,rext2);
info->text[MAX_LEN]='\0';
txtline *q = new txtline;
strcpy(q->text,rext1);
len_str = strlen(q->text);
q->text[len_str] = '\0';
q->prior=info;
info->next=q;
q->next=NULL;
last = q;
}
else
{
strcpy(rext1,info->text);
strcpy(info->text,rext);
strcat(info->text,rext1);
len_str = strlen(info->text);
info->text[len_str] = '\0';
}
}
void insert(char str[],int linenum,int position)///插入文字到一行的中间
{
txtline *info;
int len,i,length,len_str=strlen(str);
char rext_str[MAX_LEN],nostr[2]= {""},rext_str2[MAX_LEN];
info = start;
while(info && info->num != linenum)
info=info->next;
if(info == NULL)
cout<<"不存在该行!"<<endl;
else if(position < 0 )
cout<<"不存在该列!"<<endl;
else
{
length = strlen(info->text);
if(length < position )
{
len = position -length -1;
for(i=0; i<len; i++)
strcat(info->text,nostr);
strcat(info->text,str);
}
else if(length == MAX_LEN)
{
strcpy(rext_str2,&info->text[length-len_str-1]);
strncpy(rext_str,&info->text[position - 1],length-len_str-position);
strcpy(&info->text[position-1],str);
strcat(info->text,rext_str);
info->text[MAX_LEN]='\0';
info = info->next;
MoveBack(info,rext_str2);
}
else
{
MoveBack(info,str);
}
}
cout<<"\t成功操作"<<endl;
}
void MoveForward(txtline *T)
{
txtline *p=T,*q=T->next;
int len1 = strlen(p->text),len2=strlen(q->text);
char str1[MAX_LEN],str2[MAX_LEN];
while(len1+len2>MAX_LEN&&q)
{
strncpy(str2,q->text,MAX_LEN-len1);
strcat(p->text,str2);
strcpy(str1,&q->text[MAX_LEN-len1]);
strcpy(q->text,str1);
p = p->next;
q = q->next;
}
if(q)
{
strcat(p->text,q->text);
p->next=NULL;
delete q;
last = p;
}
}
void deletestr(int linenum,int position,int length)///删除一个字符串
{
txtline *info;
char rest_str[MAX_LEN];
info = find(linenum);
if(info==NULL)
cout<<"该行无字符!"<<endl;
else
{
if(strlen(info->text)<= (position + length))///本行的字符长度<=待删除的列号+删除长度,直接在当前位置插入'\0'
info->text[position] = '\0';
else
{
strcpy(rest_str,&info->text[position + length]);
strcpy(&info->text[position],rest_str);
MoveForward(info);
}
cout<<"删除字符串成功!"<<endl;
}
}
void delete_text(int linenum)///删除一行文字
{
txtline *info,*p;
info = start;
while((info->num<linenum)&&info)
info= info->next;
if(info->next == NULL)
cout<<"该行不存在"<<endl;
else
{
p = info->next;
if(start == info)
{
start = info->next;
if(start)
start->prior=NULL;
else
last = NULL;
}
else
{
info->prior->next = info ->next;
if(info!=last)
info->next->prior=info->prior;
else
last = info ->prior;
}
delete info;
while(p)
{
p->num--;
p=p->next;
}
cout<<"删除文本成功!"<<endl;
}
}
int findstr(char *to_find)///查找字符串
{
txtline *info;
int i=0,find_len,found = 0,position;
char substring[MAX_LEN];
info = start;
lnum = 0;
find_len = strlen(to_find);
while(info &&!found)
{
i = 0;///行间循环
while(!found && (i<=strlen(info->text)-find_len)) ///行内查找
{
strncpy(substring,&info->text[i],find_len);
substring[find_len] = '\0';
if(strcmp(substring,to_find)==0)
{
found = 1;
lnum = info->num;
}
else
i++;
}
info=info->next;
}
if(found)
position = i;
else
position = NOT_FOUND;
return position;
}
txtline* find(int linenum) ///查找指定行是否存在
{
txtline *info;
info = start;
while(info)
{
if(linenum != info->num)
info = info->next;
else
break;
}
return info;
}
void printline(int linenum)///打印一行文字
{
txtline *info;
info = find(linenum);
if(info)
cout<<info->num<<" : "<<info->text<<endl;
else
cout<<"该行不存在";
}
void list() ///显示
{
txtline *info;
info = start;
while(info)
{
cout<<info->num<<" : "<<info->text;
info = info->next;
cout<<endl;
}
cout<<endl;
}
void save() ///保存文件
{
txtline *info;
char *p;
FILE *fp;
if((fp = fopen("D:\\项目2\\text.txt", "w+"))==NULL)
{
cout<<"\t文件打不开!"<<endl;
exit(0);
}
cout<<"\t正在存入文件!"<<endl;
info = start;///info指向第一个字符
while(info)
{
p = info->text;
while(*p)
putc(*p++,fp);///将p指向的字符输到fp文件中
putc('\n',fp);
info=info->next;
}
fclose(fp);
cout<<"\t存入成功"<<endl;
}
void load() ///读取文件
{
txtline *info,*temp;
char c;
FILE *fp;
int inch,i;//行计数器
temp = NULL;
fp=fopen("D:\\项目2\\text.txt", "r");
if(fp == NULL)
{
cout<<"\t文件不存在!"<<endl;
cout<<"\n\t请按照提示进行创建你的文件"<<endl;
return ;
}
cout<<"\n\t正装入文件!"<<endl;
start = new txtline;
info = start;
inch = 1;
c=fgetc(fp);///从文件中读取一个字符
if(c==EOF)
{
cout<<"\n\t文件为空"<<endl;
cout<<"\n\t请按照提示进行创建你的文件"<<endl;
return ;
}
rewind(fp);///文件内部指针重新指向开头
while((c=fgetc(fp))!= EOF)
{
i = 0;
info->text[i] = c;
i++;
while((c = fgetc(fp))!='\n') //从文件中读取一行字符到线性表中,文件中每一行以\n为结束标
{
info->text[i] = c;
i++;
}
info->text[i]='\0';
info->num = inch++;
info->next = new txtline;
if(!info->next)
{
cout<<"\n\t内存已经用完!";
exit(0);
}
info->prior = temp;
temp = info;
info = info->next;
}
temp->next=NULL;
last = temp;
delete info;
start->prior = NULL;
fclose(fp);///关闭一个打开文件
cout<<"\t存入成功"<<endl;
}