综合项目二---行文本编译器

参照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;

}




  • 2
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值