行编辑器程序设计要求
编辑器基本要求
1、可以直接从设备中读取已有的文本文件
2、将编辑完毕的文本文件存入指定设备中
3、编辑的文件长度不超过64K
4、提供简单的联机帮助信息
5、操作命令采用热键命令
6、可以以插入/覆盖方式对文本进行操作
7、提供查找/替换功能,支持按行号定位
8、支持简单的块操作(块移动/复制/删除)
软件启动方法
在DOS提示符下,启动系统有两种方法:
格式一:edlin
启动系统后,进入编辑系统的提示符。
由于没有指定文件名,所以内存编辑区为空。:
格式二:edlin 文本文件路径名
启动系统后,进入编辑系统的提示符。
若指定文件存在,则将该文件装入内存。
若指定文件不存在,则文件名是编辑完成后要存入磁盘的文件名。内存编辑区为空。
编辑软件的状态
编辑软件分为两种状态:
状态一:编辑命令状态(命令态)
输入、处理各种行编辑命令。所输入的内容要根据事先定义的编辑命令进行解释,完成规定的操作。
编辑命令状态提示符:*
状态二:行输入状态(输入态)
输入文本行。所输入内容全部作为文本存入文件中。
输入态提示符:无
编辑状态之间的转换方法:
由命令态进入输入态:使用编辑命令
由输入态进入命令态:连续两行只有回车
例如:编辑软件的状态
原来的状态(输入态):
123456[ENTER]
12345678 abcdefg[ENTER]
[ENTER]
[ENTER]
进入新的状态(命令态),屏幕显示:
* _[光标]
内存中保存的数据:
123456\n
12345678 abcdefg\n
编辑软件的基本性能指标
每行可以编辑处理最长不超过127个字符
最多可以同时编辑512行,如果一个文件行数超过512行,要可以分段处理
支持常见的编辑命令
关于编辑命令的说明
编辑命令只能在命令状态使用。如果没有特殊说明,执行编辑命令之后,编辑系统仍然保持命令状态。
命令行均以[ENTER]为结束标记。
其它约定的符号和术语
当前行:指正在编辑的行
默认范围:指没有特殊指明范围时命令的作用范围
[ ] 指表示可选项目
# 指文本的行号
stri 指字符串i
length 指长度
\ 指转义符号
定位当前行
#
直接输入行号。
如果输入的行号在文件的范围,将指定的行作为当前行,则后续的操作的默认范围全是针对当前行进行的。
如果输入的行号小于1,则定位当前行为第1行。
如果输入的行号超过正在编辑的文件最大行号,则定位最后一行为当前行。
插入命令
输入插入命令之后,系统由命令状态进入输入状态。
格式1:i
在当前行的后面插入新的文本行。
格式2:i #
在指定行号 # 的后面插入新的文本行。
例如:
要在文件的最前面插入新行:i 0
新行为第 1 行。
要在第200行的后面插入新行:i 200
新行为第 201 行。
追加命令
输入追加命令,系统进入输入状态。
格式:a
将新输入的行依次追加到文件的最后面
特别说明:使用插入或追加命令进入输入状态后,允许用户连续输入多行,只有当“连续两行只有回车”时,才退出输入状态返回编辑命令状态。
显示命令
格式1:l
以当前行为中心,加行号显示当前行前后各10行文件内容。
例如:当前行为21行,则屏幕显示如下
11: abcdefghijklmn11
......
21: abcdefghijklmn21
22: abcdefghijklmn22
......
31: abcdefghijklmn31
显示命令
格式2:l #
以指定行号 # 中心,加行号显示当前行前后各10行文件内容。
例如:若执行“ l 21 ”则屏幕显示如下
11: abcdefghijklmn11
......
21: abcdefghijklmn21
22: abcdefghijklmn22
......
31: abcdefghijklmn31
显示命令
格式3:ln
以当前行为中心,不加行号显示当前行前后各10行文件内容。
例如:当前行为21行,则屏幕显示如下
abcdefghijklmn11
......
abcdefghijklmn21
abcdefghijklmn22
......
abcdefghijklmn31
显示命令
格式4:ln #
以指定行号 # 中心,不加行号显示当前行前后各10行文件内容。
例如:若执行“ ln 21 ”则屏幕显示如下
abcdefghijklmn11
......
abcdefghijklmn21
abcdefghijklmn22
......
abcdefghijklmn31
删除命令
格式1:d
删除当前行。
例如:当前行为第21行,文件内容是
abcdefghijklmn20
abcdefghijklmn21
abcdefghijklmn22
则执行 d 命令后,文件的内容是:
abcdefghijklmn20
abcdefghijklmn22
删除命令
格式2:d #
删除文件中指定行号的内容。
例如:文件内容是:
abcdefghijklmn20
abcdefghijklmn21
abcdefghijklmn22
则执行命令 d 21 后,文件的内容是:
abcdefghijklmn20
abcdefghijklmn22
查找命令
格式1:f str # length
从指定行号#开始的长度为length行中查找字符串str。
例如:文件内容是:
abc defghij klmn20
ab c defghi jklmn21
ab c defgh ijklmn22
ab cdefgh ijklmn23
abc def ghijklmn24
则执行命令:f abc 20 5,屏幕显示:
20: abc defghij klmn20
24: abc def ghijklmn24
替换命令
格式1:c str1/str2
在当前行中将str1替换为str2。
例如:文件当前行的内容是:
ab cdefghij klmn20abcedf
则执行命令:c ab/12345,屏幕显示:
12345 cdefghij klmn2012345cedf
替换命令
格式2:c str1/str2 # [length]
从指定行#开始,将总共length中将str1替换为str2。
例如:文件20行至22行的内容是:
ab cdefghij20
1233 4545 65 aaaa21
klmn20abcedf22
则执行命令:c ab/12345 20 3,文件变为:
12345 cdefghij20
1233 4545 65 aaaa21
klmn2012345cedf22
读入命令
格式1:r str
从指定的文件str中,读入文件存在当前行的后面。
例如:假设磁盘flie包含两行文本,正在编辑的文件的当前行的内容是:
ab cdefghij20
123 456 7890
则执行命令:r file,文件变为:
ab cdefghij20
new file line 1
new file line 2
123 456 7890
读入命令
格式2:r str #
从指定的文件str中,读入文件存在行号为# 的后面。
例如:假设磁盘flie包含两行文本,正在编辑的文件的当前行20行的内容是:
ab cdefghij20
123 456 7890
则执行命令:r file 20,文件变为:
ab cdefghij20
new file line 1
new file line 2
123 456 7890
读入命令
格式2:r str #
从指定的文件str中,读入文件存在行号为# 的后面。
例如:假设磁盘flie包含两行文本,正在编辑的文件的当前行20行的内容是:
ab cdefghij20
123 456 7890
则执行命令:r file 20,文件变为:
ab cdefghij20
new file line 1
new file line 2
123 456 7890
复制命令
格式:p #1 length #2
从文件的指定行 #1 开始共 length 行,复制到行号为 #2 的后面。
例如:假设的文件的20行的内容是:
ab cdefghij 20
ab cde fg hij 21
ab c d e f g h i j 22
则执行命令:p 20 2 21,文件变为:
ab cdefghij 20
ab cde fg hij 21
ab cdefghij 20
ab cde fg hij 21
ab c d e f g h i j 22
存盘不退出文件命令
格式:s
向磁盘中保存文件,然后保持编辑状态。
若还没有文件名,则要提示用户输入文件名,然后再存盘。
存盘退出命令
格式1:e
向磁盘中保存文件,然后退出编辑器。
若还没有文件名,则要提示用户输入文件名,然后再存盘退出。
不存盘退出文件命令
格式:q
不保存文件,直接退出编辑器。
若文件已经修改过,则要提示用户是否确实需要退出,要在确认后再退出。
帮助命令
格式1:h
显示全部命令的功能及其格式。
格式1:h str
显示指定命令str的功能及其格式。
另存文件命令
格式1:w str
将当前文件另存为名为str的新文件。另存完成之后,仍然继续编辑原来的文件。
块另存文件命令
格式1:w str # length
将当前文件中从 # 开始的共 length 行另存为名为str的新文件。另存完成之后,仍然继续编辑原来的文件。
文件装入命令
格式:swap #
对于当前正在编辑的文件,从 # 开始装入不超过512行。
装入新的内容之后,原来编辑的内容要保存在磁盘中。
特别注意:此命令与其它命令有密切的相关性,要统一考虑。
方案1――大数组按行存储方式
char str[500][128];
特点:
按行存储,一个自然行占数组一行。
算法简单,实现方便
效率低,每行的平均空闲率为:50%。
在文件的中间插入一行或删除一行时,要移动许多行,平均移动率为:50%。
方案2――大数组紧密存储方式
char str[500][128];
特点:
紧密存储。按字符进行存储,自然行之间用\n分隔,没有空白的字符。
内存使用效率提高,但算法复杂
在文件的中间插入一个字符或删除一个字符时,要移动后续字符,平均的字符移动率为:50%。
定位行困难。
方案2――大数组紧密存储方式
char str[500][128];
特点:
紧密存储。按字符进行存储,自然行之间用\n分隔,没有空白的字符。
内存使用效率提高,但算法复杂
在文件的中间插入一个字符或删除一个字符时,要移动后续字符,平均的字符移动率为:50%。
定位行困难。
特点:
每行信息和逻辑清晰。
可以动态申请/释放行存储空间,内存使用率提高。
行存储平均效率50%。
定位行/插入行/删除行/复制行的算法简单。
产生了 内存碎片的新问题。
方案4――行节点+不定长数组
char * line[500], * str;
str = ( char * )
malloc( line_length );
特点:
存储效率进一步提高。
产生了更为严重的 内存碎片的问题。当系统长时间运行的时候,可能会造成系统死机。
方案5――行节点+块
char * line[500], * str;
str = ( char * )
malloc( block_size );
特点:
动态申请定长块;
块内采用紧密存储方式,每行用\n标识,整个块用\0标识结束结束;
每行通过行指针指明;
算法复杂,增加了对块的控制。插入时要增加新块,删除时要释放空块...
数据结构设计是算法设计的基础,在确定了数据结构的基础上才能确定算法。
需要设计的主要算法:
插入新行
删除一行
文件中字符串查找和替换
行显示
行定位
大文件的存储与交换
----------------解决方案--------------------------------------------------------