《(c语言课程设计)C语言文本编辑器.docx》由会员分享,可在线阅读,更多相关《(c语言课程设计)C语言文本编辑器.docx(106页珍藏版)》请在taowenge.com淘文阁网|工程机械CAD图纸|机械工程制图|CAD装配图下载|SolidWorks_CaTia_CAD_UG_PROE_设计图分享下载上搜索。
1、(C语言课程设计)C语言文本编辑器文本编辑器文本编辑器是最常用的文档创建和编辑工具。 随着计算机科学与技术的发展,用来处理文本的 编辑器随处可见,并且形式多样。比如,Windows 下的记事本,写字板,EditPlus,UltraEdit等都 是十分优秀的文本编辑器和处理工具。在本章 中,我们将向读者讲解如何利用C语言来发展 开发个简易的文本编辑器。1 设计目的利用C语言的单链表数据结构及相关函数, 本章编程实现了一个与DOS操作系统下的Edit 相似的文本编辑器。再次文本编辑器中,用户能 够通过快捷和选择菜单项,完成基本的文本编辑 器和文件处理工作。通过文章的介绍,读者能够了解文本编辑器 的
2、开发过程,掌握菜单的开发技巧,加深对文件 操作的理解。更重要的是,希望此程序能抛砖引 玉,引领读者掌握编程的方法和技巧,开发出更 优秀的程序。2 功能描述,文本编辑器主要由五大功能模块构成,它们分别是文件操作模块,文本编辑模块,剪切操 作模块,菜单控制模块和帮助及其它模块。下面 分别简要介绍功能模块的功能。(1)文件操作模块。在文件操作模块中, 主要完成文件的创建,打开,保存和另存操作。 用户能够选择File菜单上的New子菜单来完成 新建文本文件操作;选择File菜单上的Save子 菜单来完成保存文件操作选择File菜单上的 Open子菜单来完成打开文件操作;选择Flie菜 单上的Save
3、as子菜单来完成文件的另存为操 作。在文件的打开,保存和另存为操作中,系统 会提示用户输入文件路径及文件名。值得一提的 是,当用户打开个文件时,指定的文件必须存 在,否则系统会报错。(2)文本编辑器模块。在文本编辑器模块 中,主要完成在编辑窗口中以添加或插入的方式 输入字符,删除光标所在当前位置的单个字符或 前个位置的单个字符,朝上下左右4个方向的 光标移动操作。当光标所在位置及后面的位置没 有字符时,系统会以添加的方式输入字符;当光 标所在位置及后面的位置有字符时,系统会已插 入的方式输入字符。用户能够使用Backspace键删除光标前个字符,也能够使用Del键删除 当前位置的字符或删除Ct
4、rl+左移(右移)键i 选定了的多个字符。用户能够使用左移键( + ), 右移键(一),上移键(t )和下移键(I )来移 动光标位置。(3)剪贴板操作模块。在剪贴板操作模块 中,主要完成对已选定文本的剪切,复制,粘贴 工作。如果用户要剪切文本以便能够将它移动到 其它位置,可通过Ctrl+X左移键(右移键)先 选定文本,然后选择Edit菜单上的Cut子菜单 或按Ctrl+X快捷键来完成剪切任务。如果用户 要复制文本以便能够将它黏贴到其它位置,必须 先选定文本,然后选择Edit菜单上的Copy紫菜 单或按Ctrl+C快捷键来完成复制任务。如果用 户要粘贴剪切或复制的文本,必须将光标置于要 粘贴文
5、本的位置,然后选择Edit菜单上的Paste 子菜单或按Ctrl+V快捷键来完成粘贴任务。(4)菜单控制模块。在菜单控制模块中, 主要完成菜单的显示。光带条在子菜单之间的上 下移动或菜单之间的左右移动和子菜单项的选 取。本文本编辑器共有Flie,Edit和Help3个子 菜单项,用户能够分别按F1,F2和F3功能键来完成这3个菜单项的调用,即显示某项菜单。用 户可按光标上移或下移键在某菜单项的子菜单 之间循环移动,也可使用光标的左移或右移键在 3个菜单项之间循环移动。当光带移动到某个字 菜单项上时,用户此时可使用Enter键来选取相 关菜单选项。(5)帮助及其它模块。在帮助及其它模块 中,主要
6、完成系统功能及按键的简要介绍。其它 模块包括文本的快速预览和窗口的显示。用户可 按F10功能键来打开快速预览窗口,在快速预览 窗口中没有功能菜单条。主窗口要有菜单栏,文 本编辑区和状态栏三大部分构成,菜单栏用来显 示菜单项,文本编辑区主要用来文本字符的输 入,删除等操作,状态栏主要用来显示当前光标 在文本窗口中的坐标值。注意:Turbo ,共有80列(或40列),25行的文本单元,每个单元包括个字符和一个属性, 字符即ASCII码字符,属性规定该字符的颜色和强度。同时,他还规定整个屏幕的左上角坐标为(1, 1), 右下角坐标为(80, 25).并规定沿水平方向为X轴,方向朝右;眼垂直方向为Y轴
7、,方向朝下.3 总体设计功能模块设计,简单描述了各功能模块的作用,下面分别 介绍各功能模块的具体设计。在介绍各功能模块 的具体设计之前,有必要先描述一下主程序的执行流程。1 .程序执行主流程,它是在main 函数中实现的。他首先 初始化一些全局变量及结构数组,接着调用 drawmain()函数来显示主窗口,然后调用 while(l)进入主循环,等待用户按键,最后程序 根据用户的按键值,进行相应的处理,完成文本 编辑的相关工作。(1)若按键为常规字符,即其ASCH码大 于32小于127,则继续判断在文本编辑区的当 前光标位置有没有字符,若有字符,则调用 insert。函数,将此字符插入在当前位置
8、,否则在 判断没有满行后,将此字符添加在单链表的数据 域中,若此行已满,则执行添加新行操作。(2)若按键为Enter键,则将光标移至下 一行的行首,等待用户输入新的字符。(3)若按键为光标移动键(左,右,上, 下)且移动后的位置满足相关条件,则执行 gotoxy()操作,将光标移动至目标位置。(4)若按键为Backspace键,则将调用 Del()函数将光标的前个字符从单链表中删除; 若按键为De!键,也将调用del()函数将光标的当前位置的字符从单链表中删除。(5)若按键为Ctrl开头的按键,则执行与 其相关的操作。具体来说,若为Ctrl+左移键 (一),则将选定当前光标的位置开始向右的一
9、个字符,若按住Ctr!键不放,连续按右移键, 能够选定多个字符。若为Ctrl+左移键(一),则 将执行与以上相同的操作。若为Ctrl+X键,则 将选定相关内容保存起来,且从单链表中删除选 定的字符后重新显示单链表的内容。若为Ctrl+C 键,则将选定的相关内容保存起来,重新显示单 链表中的内容(目的:为了去除字符的底色)。若 为Ctrl+V键,则调用insert。函数将保存起来的 字符插入在单链表中,并重新显示单链表中的内 容。(6)若按键为F10键,则调用qview()函数, 实现文本的快速预览。若按键为F1,F2,F3功能键,则调用menuctrl。 菜单控制函数,在此函数中完成案件的具体
10、判断 和执行相应功能操作。若为F!键,则调用File 菜单;若为F2键,则调用Edit菜单;若为F3 键,则调用Help菜单。2 .文件操作模块在此模块中,主要实现文件的新建、打开、保存 和另存为操作。在此系统中,文件的新建操作实 现比较简单,文件另存为操作与保存操作类似, 下面重点介绍在此文本编辑器程序中,文件的打 开和保存操作的具体设计和实现。在介绍之前, 我们先简单描述一下程序中用到的保存数据的 数据结构。在此程序中,共有两种类型的单链表, 我们称其为行单链表和列单链表,个列单链表 用来保存一行的字符,有多少行即有多少个这样 的单链表。行单链表只有一个,它的每个节点的 数据域用来保存不同
11、列单链表的首节点的地址。 例如,第4行第4列的字符保存在行单链表的第 4个节点的数据域所指的列单链表的第4个节点 的数据域中。有关具体数据结构的定义,在后面 的小节中会有具体介绍。1)打开文件,它首先提示用户输入要打开文件的文件名, 若该文件不存在或由于其它原因打开失败,则会 结束文件打开操作。若文件成功打开并且文件指 针没有到文件尾,则从文件中一次读取个字 符,并将该字符添加到列单链表节点中,直至 遇到换行符(ASCII码10)或连续读取字符个数大于76 (在此文件编辑器中,每行最多为76 个字符)。当列单链表形成后,它的首地址将被 保存至行单链表的相应节点的数据域中,如此动 作,直至文件指
12、针指向文件尾部而结束。注意:由于本程序中每行以回车符(ASCII码 为13)结束,而当用Windows的记事本创建 个文本文件,打开此文件并用fgetc()函数读取 时,程序写入列单链表节点中的值是ASCII码 为13的回车符。2)保存文件保存文件操作主要完成将单链表中的数据写入 文件中的任务,它的具体实现流程如下。(1)用户输入个保存此单链表数据的文件 名。(2)以只写方式打开此文件,若成功打开此文 件,则执行步骤(3);否则退出。(3)读取行单链表中的节点数据域的值,若值 不为空,则执行步骤(4);否则执行步骤(6)。(4)依次读取行单链表节点中保存的首地址 的相应列单链表节点的数据域的值
13、,若其值 为回车符,则用换行符替代后将其写入文件 中;否则直接将其值写入文件中,直至该列单链表中指针域为NULL的最后个元素 结束。(5)读取行单链表中的下个节点,并跳至步 骤(3)(6)关闭文件,退出。3 .文件编辑模块在文件编辑模块中,主要完成以添加或插入的方 式输入字符、删除光标所在的当前位置或前个 位置的单个字符、朝上下左右4个方向的光标的 移动操作。下面介绍这4个功能的具体设计与实 现。1)添加字符当光标处在文本编辑的最后一行的位置且光标 后面没有字符时,若此时输入字符,程序会判断 一行中字符的个数,若字符个数不等于76,则 在当前的列单链表的最后个节点中保存输入 的字符,然后添加一
14、个新的节点来保存下个输 入的字符:若等于76,则在当前的列单链表的最 后个节点中保存输入的字符,然后在行单链表 中添加一个新节点用来保存下一行的列单链表 的首地址,添加一个新的列单链表节点来保存下 个用户输入的字符。2)插入字符若光标所在处已经存在字符,当用户在当前位置 输入字符时,程序会调用insert。函数将输入的 字符在光标所在的位置处在列单链表中插入,插 入完成后,会调用test。函数来检查各行是否满 足只有76个字符的条件,若不满足此条件,则 在此函数中会对多出的字符进行处理。下面分别 对列单链表中字符的插入过程和单链表的检查 过程进行介绍。若在第m行,第!列的位置插入一个字符,其
15、insert。过程描述如下:(1)定位至行单链表中的第m个节点,得到 这个节点的数据域的值,其值为对应列单链 表中第一个节点的地址。(2)定位至列单链表中的第n-1个节点。(3)创建一个新的列单链表节点,用其数据域 保存输入的字符。(4)若字符插入在第m行第1列,则直接将 行单链表中第m个节点的数据域的值改变 为新的列单链表节点的地址,新的列单链表 节点的指针域指向列单链表中原来的第1个 节点。若字符不是插入在第m行第1列,则执行简单的单链表中插入节点的操作。(5)插入此字符后,调用test。函数,从第m 行开始检查各行是否满足每行只允许有76 个字符的条件,若不满足此条件,则必须进 行处理。
16、其test()检查处理过程描述如下:(1)用指针tail指向已经插入了新节点的列 单链表中的最后一个节点。(2)若此单链表中节点数超过76个,则指针 pl会指向此列单链表中的第76个节点,指 针p2指向第77个节点,并将pl所指节点 的指针域设置为NULLO(3)若tail所指节点的数据域为Enter键 (ASCII为13)且在行单链表中只有m个 节点,则在此行单链表中添加一个新的节 点,新节点的数据域为p2的值,指针域为 空,并将m节点的指针域指向它;若tail所 指节点反而数据域为Enter键(ASCII为13) 且在行单链表中有多于m个节点,与上面不 同的是,它执行的是在行单链表插入一个
17、新 的节点的操作。(4)若tail所指节点的数据域不是回车符,pl的数据域为回车符并且行单链表中只有m 个节点,则在行单链表中添加一个新的节 点,新节点的数据域为p2的值,指针域为 空,并将第m节点的指针域指向它;若tail 所指节点的数据域不为回车符并且行单链 表中有多于m节点,则将tai!的指针域指向 行单链表中第m+1个节点所指的列单链表 的首节点,并将行单链表中第m+1个节点 的数据域修改成指针p2的值,并对行单链 表中第m+1个节点所指的列单链表进行 test()检查,相似的处理过程至行单链表中的 最后个节点结束。3)删除字符当用户按下De!键时,系统会调用del。函数在单 链表中删
18、除当前光标所在处的字符;当用户按下 Backspace键时,系统也会调用这个函数在单链 表中删除当前光标所在处前个位置的字符。若在第m行、第!列的位置删除个字符,其 在列单链表中删除个节点的操作域插入工作 十分相似,所以这里重点介绍删除该字符后,单 链表中数据的前移工作过程。(1)在相应的列单链表中删除第n个节点。(2)判断第m行是否存在并且判断在此行中 是否有字符,若第m行不存在,或此行中没 有字符,则结束字符删除过程,否则执行步 骤(3)(3)用tai!保存第m行相应列单链表中最后 个节点的地址,并将最后个节点的指针 域保存为第m+!行中相应列单链表的第一 个元素的地址。(4)计算出第m行
19、中没有字符的位置的个数 num,然后在第m+!行的相应列单链表中截 取num个节点,并将行单链表中的第m+1 节点的数据域改为相应列单链表中的第 num个节点后的节点的地址。(5)调用m+语句,是变量m增1,跳至步 骤(3),开始对下一行进行处理。4)移动光标移动光标的操作主要利用gotoxyO函数来实现, 过程非常简单,只需对当前的光标位置和移动方 向进行判断后,即可执行gotoxy()过程。例如, 如果当前光标在第m行第1列,且按下了光标 左移键,只需将光标移至第m-1行,第76歹1。在剪切板操作模块中,主要完成对已选定文本的 剪切、复制和粘贴工作,因此剪贴板操作与文本 选定工作密切相关。
20、下面分别介绍文本的选定和 对选定文本的剪切、复制和粘贴操作的具体实 现。1)选定文本用户可按Ctrl+v或Ctrl+来选定文本,就具体 实现而言,两者基本相同。在介绍选定文本的实 现过程之前,先简要介绍个全局的结构数组 r,它的元素的类型为record结构体类型,每 个元素可保存一个字符的x坐标、y坐标和字 符值。其文本选定的实现过程如下:(1)当用户按下Ctrl+v或Ctrl+键时,程序 将当前光标位置向左或向右移动个位置。(2)当前光标所在位置的字符的x坐标、y坐 标和字符值保存在数组元素rvahie中 value从开始,若按减为Ctrl+,value值在原来基础上每次减!.(3)调用Co
21、lorview。函数,用不同的颜色来 显示已经选定的当前文本,以达到突出选定 文本的效果。2)剪切用户可按Ctrl+X键或通过Edit菜单选项来剪切 选定的文本,若之前没有选定的文本,此按键无 效。它的实现过程如下:(1)若全局变量value的值大于 (大于表示 已经有文本选定),则执行下面操作。(7)(2)保存当前位置的坐标,利用循环语句,依 次利用x至xvahie-l数组元素保存已选定字 符的坐标,调用del 函数在单链表中一次删 除个选定的字符。(3)利用全局变量backup保存value的值后, 将value赋值为(4)重新在文本编辑器中显示单链表中保存的 所有字符,并将光标置位到原来
22、的位置。3)复制用户可按Ctrl+C键或通过Edit菜单选项来复制 选定的文本,复制操作的实现比剪切操作简单, 它的实现过程如下:(1)保存当前位置的坐标。(2)利用全局变量backup保存value的值后, 将value赋值为(3)重新在文本编辑器中显示单链表中保存 的所有字符,并将光标置位到原来的位置。4)粘贴用户可按Ctrl+V键或通过Edit菜单选项,完成 粘贴操作。这操作必须在剪切或复制操作之后 出现。它的具体实现过程如下:(1)若全局变量backup的值大于 (大于 表示已经有字符放入了剪贴板数组)中,则 执行下面的操作。(2)保存当前位置的坐标,利用循环语句,依 次利用x至xba
23、ckup-l数组元素保存已 选定字符的坐标和字符值,调用insert 函数在单链表中一次插入一个字符。(3)重新在文本编辑器中显示单链表中保存 的所有字符,并将光标置位到原来的位置。5.菜单控制模块在菜单控制模块中,主要完成菜单的显示、光带 条在子菜单之间的上下移动或菜单之间的左右 移动以及子菜单项的选项工作。下面分别介绍这 3项功能的具体实现。1)显示菜单用户可按Fl、F2和F3功能键来分别调用File、 Edit和Help菜单,即完成菜单的显示。当按下 这3个功能键中的某个功能键时,程序会调用 menuctrl ()函数来完成菜单的调用操作。在 menuctrl 函数中,会根据功能键的键值
24、调用 drawmenu (value, flag)函数,参数 value、flag 都为局部变量,分别用来保存调用某个菜单、某 个菜单下的第几个菜单选项。例如,按F1键后, 它的默认值为drawmenu ( 0,0 ),表示绘制File 菜单及其5个菜单选项,并将菜单选择光带条置 于第一个菜单选项上。下面简要描述一下draw (value, flag)函数的过程。(1)先取value除以3的余数m (因为有3个 菜单项,所以除数选择3),根据m的值来 绘制不同的菜单。m的取值为、1、2、。当 m等于时,表示绘制File菜单;其余类推。(2)然后绘制菜单的边框及菜单选项值。(3)取File除以x
25、的余数t, x的取值视m的 取值而定,如当m=5时,x=5,因为File菜 单下有5个选项。(4)根据t的值,用不同的前景色和背景色在 原来的位置重新显示菜单选项,以达到光带条的效果。2)移动菜单光带条当用户按Fl、F2和F3中的某个功能键调用了 某个菜单后,可继续按光标左移、右移、上移和 下移键来实现菜单之间的切换和菜单选项之间 的切换。(1) 若为左移键,则调用drawmenu ( value, flag)函数,将切换至某个菜单的左边邻居 菜单。若当前菜单为最左边的File菜单,则 切换至最右边的Help菜单。若为右移键, 贝调用 drawmenu (+value, flag)函数。(2)
26、 若为上移键,则调用drawmenu (value, -flag)函数;若为下移键,则调用drawmenu (value, +flag)函数。3)选取菜单当用户将光带选择条置于某个菜单选项上时,可 按Enter键来选取该菜单选项。选取菜单操作的 实现比较简单,它主要利用a= (value%3) *10+flag%b来计算出选择的菜单选项的编号。 选取不同菜单选项后,a的值不同。这样,程序 可根据a的值,返回给main 函数不同的标 记,在main 函数中,可根据标记的不同来执行相关功能。6.帮助及其它模块帮助模块主要用于提示用户如何使用本软件,它 的实现非常简单。同样,文本的快速预览模块是 在
27、原来主窗口显示模块的基础上,去除了菜单的 显。主窗口主要由菜单栏、文本编辑区和状态栏3大 部分构成。菜单栏用来显示菜单项,文本编辑区 主要用来完成文本字符的输入、删除等操作,状 态栏主要用来显示当前光标在文本窗口中的坐 标值。它主要利用文本窗口的gotoxy 函数和 cprintf ()函数来实现,这里需要对文本窗口的 坐标进行仔细设计。本程序定义了 3个结构体,分别与剪贴板、列单 链表和行单链表相关。下面分别介绍这3个结构 体及几个全局变量。1 .与剪贴板相关的record结构体typedef struct recordchar ch;int col Jine; record;record结
28、构体表示一个字符所具有的属性,当用 户使用相关按键选定文本后,选定的文本保存在 record结构体类型的数组中。结构体中各字段表 示的意义如下。char ch:保存个选定的文本字符。int col, line:分别保存选定字符所在位置的x轴 坐标和y轴坐标。2 .与列单链表相关的node结构体typedef struct nodechar ch;struct node *next;node;node结构体定义了在个单链表中保存行中的 单个字符的结构,我们称由node类型的节点构 成的单链表为列单链表。结构体中各字段表示的 意义如下。char ch:数据域,保存一个字符。struct node*
29、next:指针域,指向列单链表中的下 个节点。3 .与行单链表相关的Hnode结构体typedef struct Hnodenode *next;struct Hnode *nextl;record;Hnode结构体定义了在个单链表中保存列单 链表首节点地址的结构,我们称由Hnode类型 的节点构成的单链表为行单链表。结构体中各字 段表示的意义如下。node *next:数据域,。指向列单链表的首节点的 地址struct Hnode*nextl:指针域,指向列单链表中的 下个节点。4 .全局变量及数组int value, backup, NUM:value 保存有值数组元 素的最大下标值,ba
30、ckup保存value的副本, NUM保存当前行中用户输入的字符个数。record r500:定义个有500个元素的结构体 数组,每个数组元素可保存一个选定的文本字符 及其坐标值。1) drawmain()函数原型:void drawmainQdrawmain。函数用于在程序中会只包括菜单栏, 编辑区和状态栏在内的主窗口。2)qview()函数原型:void qview(Hnode*q)qview。函数用于快速预览文本。q为指向行单链 表中第一个节点的指针。3) view()函数原型:viod view(Hnode*q)view。函数用于按行显示保存在单链表中的文本 字符,q为指向行单链表中第
31、一个节点的指针。4) checkQ函数原型:int check(Hnode*Hhead,int m,int n)函数用于在单链表中检查第m行,第n列位置 的字符,若为常规字符,则返回该字符;否则返回或L5) judge()函数原型:int judje(Hnode*Hhead,int m)judge。函数用于返回第m行中不包括回车符在 内的常规字符的个数。6) del()函数原型:int del(Hnode*Hhead,int m,int n)del。函数用于在单链表中删除第m行,第n列位置的字符。7) test()函数原型:int test(Hnode*Hhead,int n)test()函数
32、用于执行后,检验第n行及后面的数 据,使其满足每行不多于76个字符的规则。8) insert()函数原型:viod insert(Hnode*Hheadint m,int n,char a)insert。函数用于在第m行,第!列位置的前 个位置插入单个字符。9) control。函数原型:void control(int A,Hnode*Hhead) control。函数用于对左移键(右移键)进行响应, A为按键的整数值,Hhead为行单链表的首地 址。10) colorview。函数原型:voi colorview(Hnode*Hhead,int x,int y)colorview。函数用于
33、用不同的前、背景色现实选 择的字符。11) drawmenu。函数原型:void drawmenu(int m,int n)drawmenu函数用于画菜单,m表示第几项菜单, n表示第m项的第n个子菜单项。12) menuctrl()函数原型:int menuctrl(Hnode*Hhead,int A) memictrl。函数用于菜单控制。13) save()函数原型:void save(Hnode*head)save。函数用于将head所指的行单链表中所指 的各个列单链表中的数据域的值写入文件,文件 路径和文件名由用户指定。14) saveas()函数原型:void saveas(Hnod
34、e*head)saveasO函数用于实现文件另存工作,文件路径 和文件名由用户指定。15) opens()函数原型:void opens(Hnode*Hp)opens。函数用于从任意文本文件中读取文件内 容,保存至行单链表形式的数据结构中。)main()函数原型:void main()main。函数为程序的主控函数,。.4程序实现.源码分析程序预处理包括头文件的加载,以及结构体,常 量和全局变量的定义。/文本编辑器editor源代码*/#include #include #include #include #define LEFT 0x4b00#define RIGHT 0x4d00#defi
35、ne DOWN 0x5000#define UP 0x4800#define ESC 0x011b开操作/#define ENTER OxlcOd#define DEL 21248符/#define BACK 3592:光标左移/*f:光标右移/* )键:光标下移/* t键:光标上移/*ESC键:取消菜单打/回车键:换行/*DEL键:删除当前字/*Backspace 键:删除当前光标位置前个字符/#define CL 29440/*ctrl+一键:从右至左,选定文本/#define CR 29696/*ctrl+f 键:从左到右,选定文本/#define Cc 11779/*ctrl+c 键:
36、将选定文本,复制份到剪贴板中/#define Cv 12054/*ctrl+v 键:将剪贴板中的内容复制到当前位置*/*ctrl+x键:对选定文本,/*F1键:打开文件菜单/*F2键:打开编辑菜单/*F3键:打开帮助菜单/*F10键:进入文本快速#define Cx 11544执行剪切操作/#define Fl 15104#define F2 15360#define F3 156#define F10 17408预览模式*/int value,backup,NUM;lvalue保存有值数组元素的最大下标值, backup保存value的副本,NUM保存当前行中 的用户输入的字符个数/type
37、def struct record char ch; /保存一字符/int col, line; /*x 轴和 y 轴坐标/ record;record r500; /*定义个有500个元素的结构 体数组,保存选定的文本字符的属性/typedef struct node /定义保存行中的单个字符 的结构/char ch; /*数据域:保存一字符/struct node *next; /指针域:指向下 个结点的指针/node;/由此类型节点构成的单链表,命名为: 列单链表/typedef struct Hnode /定义保存所有列单链 表首节点的指针的结构/node *next; /指向列单链表
38、的首节点 的地址/struct Hnode *nextl; /指向下个节 点的指针Hnode;/由此类型节点构成的单链表,命名为: 行单链表/绘制文本编辑器主窗口由drawmain()函数来完 成,通过准确定位相关输出对象的坐标来完成主 窗口的绘制。主窗口共分为3个区域:菜单区, 文本编辑去和状态栏区。void drawmain() /画主窗 口 函数/int i,j;gotoxy(l,l);/在文本窗口中设置光标至(1,1)处/textbackground(7); /选择新的文本 背景颜色,7为LIGHTGRAY淡灰色/textcolor(O);/*在文本模式中选择新的字符颜色为BLACK黑
39、/insline();/*在文本窗口的(1,1)位置处中插入个空行/for(i=l ;i=24;i+)(gotoxy(l,l+i); /* (x,y)中 x 不变,y+*/cprintf(%cH,196); /*在窗口左 边输出,即画出主窗口的左边界gotoxy(80,l+i);cprintf(%cH,196); /*在窗 口 右 边,输出,即画出主窗口的右边界/)for(i=l ;i=79;i+)gotoxy(l+i,2); / 在第 2行,第2列开始/cprintf(%cn,196); / 在窗 口 顶端,输出*/gotoxy(l+i,25);/* 在第 25行,第2列开始/cprintf
40、(M%c,196); / 在窗 口 底端,输出*/)gotoxy(l,l);cprintf(H %c,196);/在窗口左上角,输出*/gotoxy(l,24);cprintf( %cn,196);/在窗口左下角,输出*/gotoxy(80,l);cprintf( %c,196);/在窗口右上角,输出*/gotoxy(80,24); cprintf( %cn,196); /*在窗口右下角,输出*/gotoxy(7,l); cprintf(H%c %cFile %c %cn,179,17179); /* | */ gotoxy(27,l); cprintf(%c%cEdit %c %c”,179
41、,17,179); /* I v */ gotoxy(47,l); cprintf(%c%cHelp %c %c”,179,17,179); /* I v */ gotoxy(5,25); / 跳至窗 口底端/ textcolor(l);cprintf(n Row:lCol:ln);gotoxy(68,25); cprintf(nVersion n);)文本字符显示输出模块的作用是通过循环读取 各单链表,酱爆错在单链表众多的字符在文本编 辑区中显示输出。(1) 通过qview(hnode*q)函数,可实现文本 字符的快速预览。(2) 通过view(honde*q)函数,可实现文本字 符在编辑区
42、域的显示。void qview(Hnode *q) /*快速预览文本:开头:#,回车:* */void view(Hnode *q); /*view()函数声明*node *p;int i;window(l,l,80,25); /*定义文本窗口大小*clrscr(); /清屏/*循环读取两个单链表中的值:q是个 指向行单链表首节点的指针,此单链表数据域的值为实际保存各行字 符的列单链表p中的首节点地址/dop=q-next; /*p指向保存行 数据的列单链表的首节点的地址/cprintf(#);/*每行开头,打印 此字符,不论前面是否有回车符*/while(p!=NULL) /循环读取单 链表
43、p中的值/(if(p-ch=13)piitch,;/*若为回车键,打印出号/elseputch(p-ch); /输出各行中的字符到预览窗口/p=p-next; /* 指向 下 个节点/)q=q-nextl; /指向下个节点/printf(”n);/*输出个回车/ while(q!=NULL);getch();clrscr();drawmain。;/*按任意键后,回到主窗口 界面/windo w(2,2,79,23);textbackground(9);for(i=0;inext;while(p!=NULL&p-ch=32&p-chch!=13&p-ch!=-l) /指针 p 不能为空, 且数据
44、域必须为常规字符/(putch(p-ch);/* 在文本 窗口中输出该字符/p=p-next; / 指向 下个节点/q=q-nextl; /指向下个节点/if(p-ch=13|p-ch=-l)&q!=NULL) gotoxy(l,wherey()+l); /*若 ch 为回车或 EOF 标 记,光标跳至下行的开始处while(q!=NULL); /*逐行逐列显示文 本字符/)程序调用 del(Honde*Hhead,int m,int n)函数来 完成删除第行、第列位置的字符。它的具体过程 在功能模块设计部分已经详细介绍。下面介绍另 外两个对字符进行检测的函数,它在字符的删 除、插入等许多操作
45、中都有用到。(1) 调用 check(Hnode*Head,int m9int n)函 数,在单链表中检查第m行、第n列位置的 字符,若为常规字符,则返回该字符;否则 返回或1.,(2) 调用 judge(Hnode*Hhead,iiit m)函数,在 单链表中统计第m行中的常规字符的总个数,并返回统计值。int del(Hnode *Hhead,int m,int n) /*del():删 除第m行,第n列位置的字符/Hnode *q,*ql;node *pl,*p2,*tail;int i,num=0J,flag=0;q=Hhead;if(n=0&m=l) return; /*第 1 行,第0列不存在/if(n=0&ml) /若为第0列字符,但 行必须大于1,执行向上行移处理*/(n=76;m=m-l;gotoxy(n,m);/*移至第 m-I 行, 第76列/flag=l; /移位的标志置1*/for(i=l;im;i+) /定位至行单链表中 的第m个元素