本程序要求完成一个简易文本编辑器,能够完成文本的录入、编辑、删除、查找,并能够完成文件的存取。
在文本编辑软件中把用户输入的所有文本内容作为一个字符串。虽然各种文本编辑软件的功能有强弱差别,但是基本操作都包括串的输入、修改、删除(包括整行删除和一行中的子串删除)、查找、输出等。通过分析,系统应该包括以下功能:
1、具有简单的文字或图形菜单界面
2、能实现串或文本块的查找、替换、删除、插入、移动操作。
3、能实现文本文件的存盘和读取功能。
4、具有友好的界面和较强的容错能力
设计思路
1、采用的逻辑结构
文本编辑器主要是针对文本进行编辑,文本的操作就是对字符的操作。文本编辑器可以从行、列两个方向进行编辑。
每一行可以看成一个线性表,线性表是一种线性结构,线性结构的特点是数据元素之间为线性关系,数据元素“一个接一个的排列”。在一个线性表中数据元素的类型是相同的,由于每一行可以存储的最大字数是相同的,行方向所有线性表的最大长度可以设置成相同的。行与行之间的关系也可以看成一个线性表。
2、采用的存储结构
线性表的存储分为两种:顺序存储和链式存储。
顺序存储是指在内存中用地址连续的一块存储空间顺序存放线性表的各元素,用这种存储形式存储的线性表称为顺序表。在程序设计语言中,一维数组在内存中占用的存储空间就是一组连续的存储区域,因此,用一维数组来表示顺序表的数据存储区域是再合适不过的。
链式存储是通过-组任意的存储单元来存储线性表中的数据元素的,为建立数据元系之间的线性关系,对每个数据元素除了存放数据元素自身的信息之外,还需要和一起存放其后继或前驱所在的存储单元的地址,这两部分信息组成一个“结点”,每个元素都如此。存放数据元素信息的称为数据域,存放其前驱或后继地址的称为指针域。只有一个存储单元地址的为单链表,有两个存储单元地址的为双链表。
考虑到实际的功能需求,每行的线性表可以用顺序存储方式,每个字符是一个节点。用数组的长度表示本行可以输入的最大字符。行与行之间的线性表采用双链表存储,每个节点包括四个区域,一个指针域prior指向上一行,一个指针域next指向下一行,一个数据域num是行号,一个数据域是本行的字符数组。程序以行和列标识文本位置,行采用双向链表存储行信息,用数组下标标识列信息,从而能够准确定位字符位置,然后进行查找、替换、插入、块移动、删除等多种操作。
#include
#include
#include
#define MAX_LEN 100
#define NOT_FOUND -1
//定义行结构体:
struct line
{
char text[MAX_LEN]; //本行文本
int num; //行号
struct line *next; //指向下一个行的指针
struct line *prior; //指向前一个行的指针
};
int lnum;
struct line *start; //指向线性表中第一行的指针
struct line *last; //指向线性表中最后一行的指针
struct line *find(int); //查找指定行是否存在
void patchup(int, int); //对当前行以后的每行的行号加1或
void delete_text(int); //删除一行文字
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 lenth); //删除一个字符串
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); //插入一个空白行
//下列函数是系统主函数,提供系统主界面,通过选择项转入执行插入、删除、查存盘、读人文件等功能的界面。
int main(void)
{
char str[MAX_LEN];
int choice;
int linenum = 1;
int number = 0;
start = NULL;
last = NULL;
load(); //打开文件,初始化线性表
do{
choice = menu_select();
switch (choice)
{
case 1: //执行插入功能
choice = menu_select_insert();//显示插入子菜单
switch (choice)
{
case 1: //插入一行
printf("\t行号:");
scanf("%d", &linenum);
enter(linenum);
break;
case 2: //插入到指定行的指定列
printf("输入插入位置一行号:");
scanf("%d", &linenum);
printf("输入插入位置-列号:");
scanf("%d", &number);
printf("要插入的字符串:");
scanf("%s", str);
insert(str, linenum, number);
break;
case 3: //退出插入
break;
}
break;
case 2: //执行删除功能
choice = menu_select_delete(); // 删除子菜单
switch (choice)
{
case 1: //删除指定行
printf("\t行号:");
scanf("%d", &li