文本编辑器c++实验报告附源代码
- 格式:doc
- 大小:82.06 KB
- 文档页数:15
用C#编写“文本编辑器”实验报告实验3 项目名称:文本编辑器1、实验目的和要求通过本实验,使得学生理解操作系统目录与文件的概念,掌握文件流的读写操作。
要求编写一个满足以下条件的文本编辑器程序。
(1)程序界面与操作系统中的记事本界面类似。
(2)程序可以打开、保存和编辑txt文本文件。
(3)程序可以查找和替换文本内容中的指定字符串2、程序代码using System;using System.Collections.Generic;using ponentModel;using System.Data;using System.Drawing;using System.Linq;using System.Text;using System.Windows.Forms;using System.IO;namespace 记事本{public partial class frmNotepad : Form{bool b = false;//布尔变量b用于判断文件是新建的还是从磁盘打开。
true表示文件从磁盘打开的,false表示文件是新建的,默认值为falsebool s = true;//布尔变量s用于判断文件是否被保存。
false表示未被保存,默认值为truepublic frmNotepad(){InitializeComponent();}/*多格式文本框TextChange的事件代码*/private void rtxtNotepad_TextChanged(object sender, EventArgs e){//文本被修改后,设置s为false,表示文件未被保存s = false;}/*【新建】菜单代码*/private void tsmiNew_Click(object sender, EventArgs e){//判断当前文件是否从磁盘打开,或者新建时文档不为空,并且文件未被保存if (b == true || rtxtNotepad.Text.Trim() != ""){//若文件未被保存if (s == false){string result;result = MessageBox.Show("文件尚未保存,是否保存?", "保存文件", MessageBoxButtons.YesNoCancel).ToString();switch (result){case "Yes"://若文件是从磁盘打开的if (b == true){//按文件打开的路径保存文件rtxtNotepad.SaveFile(odlgNotepad.FileName);}//若文件不是从磁盘打开的else if (sdlgNotepad.ShowDialog() == DialogResult.OK){rtxtNotepad.SaveFile(sdlgNotepad.FileName);}s = true;rtxtNotepad.Text = "";break;case "No":b = false;rtxtNotepad.Text = "";break;}}}}/*【打开】菜单代码*/private void tsmiOpen_Click(object sender, EventArgs e){if (b == true || rtxtNotepad.Text.Trim() != ""){string result;result = MessageBox.Show("文件尚未保存,是否保存?", "保存文件", MessageBoxButtons.YesNoCancel).ToString();switch (result){case "Yes":if (b == true){rtxtNotepad.SaveFile(odlgNotepad.FileName);}else if (sdlgNotepad.ShowDialog() == DialogResult.OK){rtxtNotepad.SaveFile(sdlgNotepad.FileName);}s = true;rtxtNotepad.Text = "";break;case "No":b = false;rtxtNotepad.Text = "";break;}}odlgNotepad.RestoreDirectory = true;if ((odlgNotepad.ShowDialog() == DialogResult.OK) && odlgNotepad.FileName != ""){rtxtNotepad.LoadFile(odlgNotepad.FileName);b = true;}s = true;}/*【保存】菜单代码*/private void tsmiSave_Click(object sender, EventArgs e){//若文件从磁盘打开并且修改了其内容if (b == true && rtxtNotepad.Modified == true){rtxtNotepad.SaveFile(odlgNotepad.FileName);s = true;}else if (b == false && rtxtNotepad.Text.Trim() != "" && sdlgNotepad.ShowDialog() == DialogResult.OK){rtxtNotepad.SaveFile(sdlgNotepad.FileName);s = true;b = true;odlgNotepad.FileName = sdlgNotepad.FileName;}}/*【另存为】菜单代码*/private void tsmiSaveAs_Click(object sender, EventArgs e)if (sdlgNotepad.ShowDialog() == DialogResult.OK){rtxtNotepad.SaveFile(sdlgNotepad.FileName);s = true;}}/*【退出】菜单代码*/private void tsmiClose_Click(object sender, EventArgs e){Application.Exit();}//【撤销】菜单代码private void tsmiUndo_Click(object sender, EventArgs e){rtxtNotepad.Undo();}//【复制】菜单代码private void tsmiCopy_Click(object sender, EventArgs e){rtxtNotepad.Copy();}//【剪切】菜单代码private void tsmiCut_Click(object sender, EventArgs e){rtxtNotepad.Cut();}//【粘贴】菜单代码private void tsmiPaste_Click(object sender, EventArgs e){rtxtNotepad.Paste();}//【全选】菜单代码private void tsmiSelectAll_Click(object sender, EventArgs e) {rtxtNotepad.SelectAll();}//【日期】菜单代码private void tsmiDate_Click(object sender, EventArgs e){rtxtNotepad.AppendText(System.DateTime.Now.ToString()); }//【自行换行】菜单代码private void tsmiAuto_Click(object sender, EventArgs e)if (tsmiAuto.Checked == false){tsmiAuto.Checked = true;//选中该菜单项rtxtNotepad.WordWrap = true;//设置为自动换行}else{tsmiAuto.Checked = false;rtxtNotepad.WordWrap = false;}}//【字体】菜单代码private void tsmiFont_Click(object sender, EventArgs e){fdlgNotepad.ShowColor = true;if (fdlgNotepad.ShowDialog() == DialogResult.OK){rtxtNotepad.SelectionColor = fdlgNotepad.Color;rtxtNotepad.SelectionFont = fdlgNotepad.Font;}}//【工具栏】菜单代码private void tsmiToolStrip_Click(object sender, EventArgs e){Point point;if (tsmiToolStrip.Checked == true){point = new Point(0, 25);//隐藏工具栏时,把坐标设为(0,25),因为菜单的高度为24tsmiToolStrip.Checked = false;tlsNotepad.Visible = false;rtxtNotepad.Location = point;//设置多格式文本框左上角的位置rtxtNotepad.Height += tlsNotepad.Height;//隐藏工具栏后,增加文本框的高度}else{//显示工具栏时,多格式文本框左上角的位置为(0,50),因为工具栏的高度25加上菜单的高度25=50point = new Point(0, 50);tsmiToolStrip.Checked = true;tlsNotepad.Visible = true;rtxtNotepad.Location = point;rtxtNotepad.Height -= tlsNotepad.Height;}}//【状态栏】菜单代码private void tsmiStatusStrip_Click(object sender, EventArgs e){if (tsmiStatusStrip.Checked == true){tsmiStatusStrip.Checked = false;stsNotepad.Visible = false;rtxtNotepad.Height += stsNotepad.Height;}else{tsmiStatusStrip.Checked = true;stsNotepad.Visible = true;rtxtNotepad.Height -= stsNotepad.Height;}}//【关于记事本】菜单代码private void tsmiAbout_Click(object sender, EventArgs e){frmAbout ob_FrmAbout = new frmAbout();ob_FrmAbout.Show();}private void tlsNotepad_ItemClicked(object sender, ToolStripItemClickedEventArgs e) {int n;//变量n用来接收按下按钮的索引号n = tlsNotepad.Items.IndexOf(e.ClickedItem);switch (n){case 1:tsmiNew_Click(sender, e);break;case 2:tsmiOpen_Click(sender, e);break;case 3:tsmiSave_Click(sender, e);break;case 4:tsmiCut_Click(sender, e);break;case 5:tsmiCopy_Click(sender, e);break;case 6:tsmiPaste_Click(sender, e);break;case 7:tsmiAbout_Click(sender, e);break;}}//计时器控件代码private void tmrNotepad_Tick(object sender, EventArgs e){tssLbl2.Text = System.DateTime.Now.ToString();}//窗体的sizechanged事件代码(为使得改变窗体大小时,状态栏随之改变)private void frmNotepad_SizeChanged(object sender, EventArgs e){frmNotepad ob_frmNotepad = new frmNotepad();tssLbl1.Width = this.Width / 2 - 12;tssLbl2.Width = tssLbl1.Width;}}}3、实验结果及程序运行界面。
记事本实验报告一、实验目的创建一个Windows窗体应用程序,实现记事本的基本功能,具体包括新建文件、打开文件、保存文件、查找等功能。
该实验的目的是掌握:(一)窗体程序的开发(二)常用控件的使用(三)常用事件的处理(四)对话框的设计和使用(五)文件访问的基本方法二、实验内容(一)主窗口Form1图1 主窗口主窗口界面如图1所示,功能包括基本编辑操作、主菜单和其它快捷键功能。
1、编辑功能用文本框实现。
2、窗口标题与文件名相一致。
未打开文件时为“无标题”,打开文件(另存为)后为文件名。
3、支持菜单的热键和快捷键。
二者的区别是前者是激活菜单且显示出该菜单项时有效,后者在任何时候有效。
4、实现新建、打开、保存和查找功能。
5、支持F3(查找下一个)。
表1 Form1控件列表using System;using System.Collections.Generic;using ponentModel;using System.Data;using System.Drawing;using System.Linq;using System.Text;using System.Windows.Forms;using System.IO;namespace WindowsFormsApplication1{public partial class Form1 : Form{public Form2 fm2 = null;public string searchText = "";public Form1(){InitializeComponent();}private void saveFile(){if (textBox1.Text.Length > 0 && textBox1.Modified) {if (MessageBox.Show("想保存文件吗?", "记事本",MessageBoxButtons.YesNoCancel,MessageBoxIcon.Warning) == DialogResult.Yes){SaveFileDialog d = new SaveFileDialog();d.Filter = "文本文件(*.txt)|*.txt|所有文件(*.*)|*.*";if (d.ShowDialog() == DialogResult.OK){FileStream fs = File.OpenWrite(d.FileName);StreamWriter sr = new StreamWriter(fs);sr.Write(textBox1.Text);sr.Flush();fs.Close();}}}}private void文件NToolStripMenuItem_Click(object sender, EventArgs e) {saveFile();textBox1.Text = "";Text = "无标题 - 记事本";}private void OpenFile(){OpenFileDialog d = new OpenFileDialog();d.Filter = "文本文件(*.txt)|*.txt|所有文件(*.*)|*.*";if (d.ShowDialog() == DialogResult.OK){FileStream fs = File.OpenRead(d.FileName);StreamReader sr = new StreamReader(fs);string s;string s1 = "";while ((s = sr.ReadLine()) != null){s1 += s;}textBox1.Text = s1;string fname = d.FileName.Substring(stIndexOf("\\") + 1);Text = fname + " - 记事本";}}private void打开OToolStripMenuItem_Click(object sender, EventArgs e) {saveFile();OpenFile();}private void保存SToolStripMenuItem_Click(object sender, EventArgs e) {saveFile();}private void查找FToolStripMenuItem_Click(object sender, EventArgs e) {if (fm2 == null){fm2 = new Form2();fm2.fm1 = this;Form2.textBox2 = textBox1;fm2.Show();}elsefm2.Activate();}private void textBox1_KeyDown(object sender, KeyEventArgs e){if (e.KeyCode == Keys.A && e.Control && !e.Shift && !e.Alt){textBox1.SelectAll();e.Handled = true;}else if (e.KeyCode == Keys.F3 && !e.Control && !e.Shift && !e.Alt) {Form2.findNext();}}}}(二)查找对话框图2 查找对话框查找对话框的界面(图2)与记事本的相同。
综合性实验文本编辑器一.实验要求1.参考系统的写字板功能,编写一个小型的文字编辑工具;2.该文档编辑器,至少完成以下功能:A、文件操作:新建,打开,保存,退出;B、编辑操作:复制,剪切,黏贴,全选;C、查找与替换:查找,替换;D、格式操作:字体,颜色等。
3.界面设计应考虑美观,操作简便等问题,应有工具栏,右键菜单;二.设计思路1、首先,设计一个整体框架。
文本编辑器有一个主的窗体form1,文件的新建,打开,保存,退出;复制,剪切,黏贴,全选;字体,颜色等都是在这个窗体上进行的。
而这些操作的进行,都需要在richtextbox上进行,并且要允许用户打开多个窗口,所以我又增加了一个窗体newform(父窗体为form1),作为用户新建时调用的窗口。
其次,可以增加一个新的窗体searchform,作为查找、替换字符串的操作窗口。
所以,总的来说,有三个窗体,form1为主窗体,newform是用户在新建时调用的窗体,searchform为用户在操作查找、替换功能时需要调用的窗体。
2、接下来,就是对各个窗体的实现了。
Form1是主窗体,上面有菜单栏,工具栏,可以新建窗口,以及支持右键菜单。
3、Newform是用户新建时调用的。
它主要就是一个窗体中放了一个richtextbox,以及支持右键菜单。
4、Searchform是一个查询、替换窗体。
上面有2个label,2个textbox,3个button。
2个textbox的作用为获取要查找的字符串,已经要替换的字符串。
3个button的作用分别为“查询”、“单个替换”、“全部替换”。
5、此文本编辑器支持新建,打开,保存,退出,复制,剪切,黏贴,全选,查找,替换,字体,颜色以及支持右键菜单。
只要把鼠标放到主窗体上,就可支持右键新建、打开;把鼠标放到richtextbox上时,就可以支持右键复制、黏贴、剪切、关闭。
四则运算核心代码:private void打开ToolStripMenuItem1_Click(object sender, EventArgs e)//打开{//OpenFileDialog openfileDialog = new OpenFileDialog();openFileDialog1.Filter = "纯文本文件(*.txt)|*.txt|所有文件(*.*)|*.*";if (this.openFileDialog1.ShowDialog()== DialogResult.OK){s_FileName= openFileDialog1.FileName;NewForm nf = new NewForm();nf.MdiParent = thi s;nf.Text = s_FileName;using (StreamReader read = new StreamReader(s_FileName)){nf.richTextBox1.Text = read.ReadToEnd();}nf.Show();}}public void savefile()//保存文件{//SaveFileDialog saveFileDialog1 = new SaveFileDialog();saveFileDialog1.Filter = "纯文本文件(*.txt)|*.txt|所有文件(*.*)|*.*";saveFileDialog1.FilterIndex = 0;saveFileDialog1.RestoreDirectory = true;NewForm nf = (NewForm)this.ActiveMdiChild;if (nf == null){MessageBox.Show("没有文档可保存!");return;}if (s_FileName.Length != 0){if (File.Exists(@s_FileName)){StreamWriter sw = null;sw = new StreamWriter(s_FileName);sw.Write(nf.richTextBox1.Text);sw.Flush();sw.Close();return;}}if (saveFileDialog1.ShowDialog() == DialogResult.OK){if (s_FileName.Length != 0){nf.richTextBox1.SaveFile(s_FileName, RichTextBoxStreamType.PlainText);}else{s_FileName = saveFileDialog1.FileName;nf.richTextBox1.SaveFile(s_FileName, RichTextBoxStreamType.PlainText);}}}private void保存ToolStripMenuItem_Click(object sender, EventArgs e)//保存{savefile();}private void查找ToolStripMenuItem_Click(object sender, EventArgs e)//查找替换功能{if (searchform == null){searchform = new searchForm();searchform.SearchAction+=new searchForm.SearchEventHandle(OnSearch);}searchform.Show();}private void OnSearch(){NewForm nf=(NewForm)this.ActiveMdiChild;this.SearchString = searchform.SearchString;start = nf.richTextBox1.Find(SearchString,start,RichTextBoxFinds.MatchCase);if (searchform.two == 1){if (start >= 0){nf.richTextBox1.SelectedText = searchform.ReplaceStr;start += searchform.ReplaceStr.Length;}else{MessageBox.Show("已到文档末尾!");start = 0;}}else if (searchform.three == 1){string replaceall=nf.richTextBox1.Text.Replace(searchform.SearchString, searchform.ReplaceStr);nf.richTextBox1.Text = replaceall;start = 0;}else{if (start >= 0) start += thi s.SearchString.Length;else{MessageBox.Show("已到文档末尾!");start = 0;}}}private void全选ToolStripMenuItem_Click(object sender, EventArgs e)//后退{NewForm nf = (NewForm)this.ActiveMdiChild;nf.richTextBox1.Undo();}private void全选ToolStripMenuItem1_Click(object sender, EventArgs e)//全选{NewForm nf = (NewForm)this.ActiveMdiChild;nf.richTextBox1.SelectAll();}三.程序运行效果图1.开始运行的界面:2、新建文档:3、文本编辑:4、文档保存5、查找:6、替换:4实验总结教你如何用WORD文档(2012-06-27 192246)转载▼标签:杂谈1. 问:WORD 里边怎样设置每页不同的页眉?如何使不同的章节显示的页眉不同?答:分节,每节可以设置不同的页眉。
C语言课设实验报告[记事本程序]班级:学号:姓名:指导老师:C语言课设实验报告#define key_down 80#define key_up 72#define key_esc 1#define key_alt_f 33#define key_alt_x 45#define key_enter 28#define key_alt_e 18int get_key();void box(int startx,int stary,int high,int width);{int i,key,x,y,l;char *w=NULL,*d=NULL,*s=NULL;FILE *fp;char *menu[]={ "File ", "Edit ","Format","View","Help"};char *red[]={ "F", "E","F","V","H"};char *f[]={ "New ", "Open" , "Save", "Another","Quit alt_x"};char *e[]={"Search","Search next","Replace","Date"};char buf[16*10*2],buf1[16*2];textbackground(3);clrscr();window(1,1,80,1);textbackground(WHITE);textcolor(BLUE);clrscr();window(1,1,80,2);for(i=0, l=0; i <5;i++){x=wherex();y=wherey();textcolor(BLACK);cprintf( " %s ",menu[i]);l=strlen(menu[i]);gotoxy(x,y); x.y等的头文件*//*功能键的扫描码的定义*//* i为循环次数的序数,key为从键盘输入的功能键,x,y 为光标的坐标,l为菜单栏中菜单的字符长度*//*w是存放输入的内容(记录的事情)的指针,*s是存放输入的文件名的指针,*d是存放输入要定时的文件的文件名的指针*/ /*菜单栏中各个菜单的定义*//*菜单栏中菜单开头要标颜色的字母的定义*//* file 子菜单中项目的定义*//*edit子菜单的定义*/ /*缓冲区的定义*//*整个大窗口的背景颜色设置*//*创建菜单栏窗口*/ /*设置菜单栏窗口背景颜色为白色,字体颜色为蓝色*//*利用循环输出menu菜单栏,有多少个菜单循环多少次。
文本编辑器的程序设计及代码示例在计算机科学领域,文本编辑器是一种用于编辑文本文件的应用程序。
它允许用户创建、修改和保存文本文件,并提供了一系列功能来方便用户进行编辑操作。
本文将介绍文本编辑器的程序设计原理,以及示范几个常见的代码示例。
一、程序设计原理文本编辑器的程序设计需要考虑以下几个方面:1. 用户界面设计:一个好的文本编辑器应具备直观友好的用户界面,提供各种操作选项和快捷键,使用户能够轻松地进行文本编辑。
2. 文本处理功能:文本编辑器应具备基本的文本处理功能,如插入和删除文本、查找和替换、拷贝和粘贴等。
这些功能需要通过合适的数据结构和算法来实现。
3. 文本格式化:文本编辑器应支持对文本进行格式化操作,如自动对齐、缩进、换行等。
4. 多标签支持:多标签功能允许用户同时打开多个文本文件,并在它们之间切换。
这要求程序设计中能够有效地管理多个文本文件的打开、关闭和切换。
二、代码示例下面是几个简单的代码示例,用于展示文本编辑器的一些基本功能。
1. 创建文本文件```pythondef create_file(filename):# 创建一个新的文本文件file = open(filename, "w")file.close()```2. 打开文本文件```pythondef open_file(filename):# 打开文本文件并返回文件对象 file = open(filename, "r")return file```3. 插入文本```pythondef insert_text(file, position, text): # 在指定位置插入文本file.seek(position)content = file.read()file.seek(position)file.write(text + content)```4. 删除文本```pythondef delete_text(file, start, end):# 删除指定位置的文本file.seek(start)content = file.read()file.seek(start)file.write(content[:end - start])```5. 查找和替换文本```pythondef find_replace(file, old_text, new_text):# 在文本中查找指定内容并替换file.seek(0)content = file.read()new_content = content.replace(old_text, new_text)file.seek(0)file.write(new_content)```6. 关闭文本文件```pythondef close_file(file):# 关闭文本文件file.close()```三、总结通过以上代码示例,我们展示了文本编辑器的一些基本功能,包括创建文件、打开文件、插入和删除文本、查找和替换文本以及关闭文件。
(完整版)c实验报告实验名称: C语言实验报告实验内容:本次实验主要针对C语言编程进行实验。
通过实验的设计和完成,检验和加深对C语言的理解和应用能力。
实验步骤:1. 实验准备在开始实验之前,需要准备好以下必要的工具和材料:- 计算机- C语言编译器(比如GCC、Clang等)- 文本编辑器(比如Notepad++、Sublime Text等)2. 实验环境搭建在计算机上安装C语言编译器,并配置好相应的环境变量。
这样可以在终端或命令提示符中执行相关的C程序。
3. 编写实验代码根据实验要求,使用文本编辑器编写C语言代码。
根据实验的要求和功能需求,合理设计和组织代码结构,包括头文件的引用、变量的定义、函数的声明和定义等。
4. 编译和运行代码在命令行或终端中使用编译器对编写好的C语言代码进行编译,并生成可执行文件。
编译命令的具体格式根据不同的编译器而有所差异,但一般形式如下:```gcc -o output_file input_file.c```其中,"output_file"表示生成的可执行文件名,"input_file.c"表示待编译的C源代码文件名。
编译成功后,通过命令行或终端执行生成的可执行文件,检查程序的运行结果是否符合预期。
5. 实验结果分析根据实际运行结果,对实验数据进行分析和归纳。
可以通过输出结果、打印特定信息或观察程序的行为来判断程序是否正确地实现了预期的功能。
6. 实验总结在实验报告中对本次实验的过程、方法、结果进行总结,并提出实验中遇到的问题和解决方法。
同时,对所学习的C语言相关知识点进行总结和归纳,以加深对相关知识的理解和记忆。
实验结果:通过本次实验的设计和实现,我成功完成了对C语言编程的实验,达到了预期的目标。
通过编写实际的代码,我巩固了对C语言语法和基本概念的理解。
在实验过程中,我遇到了一些问题,通过查阅资料和与同学的讨论,我成功解决了这些问题。
C#实验报告班级:姓名:学号:实验一文本编辑器一:实验目的及要求1.熟悉VisualC#.NET的可视化界面,掌握控件的使用。
2.掌握System.IO类的文件流操作,会处理文件。
二:实验内容:1、假设有要排序的20个数存在文件Data.txt中。
编写程序,打开该文件并将排好序的数重新写回该文件。
2、重新打开第1题创建的文件,在文件的结尾再添加10个随机数。
3、参考Windows的记事本程序,编写一个简单的文本编辑器程序。
4、编写程序,在用户选择了一个目录后,找出该目录及其子目录中所有后缀名为doc的文件。
5、假设有文本文件1.txt和2.txt。
编写程序,创建一个新的文本文件,将1.txt中的内容和2.txt中的内容重复两遍,交替写入新的文本文件,并删除1.txt和2.txt。
三:实验环境Windows XP操作系统,Visual 2005四:实验源程序及关键代码的解释主界面:(1)排序/添加随机数程序代码:using System;using System.Collections.Generic;using ponentModel;using System.Data;using System.Drawing;using System.Text;using System.Windows.Forms;using System.IO;namespace 文本编辑器设计{public partial class Form2 : Form{public Form2(){InitializeComponent();}private void Form2_Load(object sender, EventArgs e){FileStream fs = new FileStream("D:\\1.txt", FileMode.Open, FileAccess.ReadWrite);StreamReader sr = new StreamReader(fs);richTextBox1.Text = sr.ReadToEnd();sr.Close();fs.Close();}private void button1_Click(object sender, EventArgs e){FileStream fs = new FileStream("D:\\1.txt", FileMode.Open, FileAccess.ReadWrite);StreamReader sr = new StreamReader(fs);string[] myDate = sr.ReadToEnd().Split(',');sr.Close();fs.Close();for (int i = 0; i < myDate.Length; i++){for (int j = 0; j < myDate.Length - i - 1; j++){if (Convert.ToInt32(myDate[j]) > Convert.ToInt32(myDate[j + 1])){string t;t = myDate[j];myDate[j] = myDate[j + 1];myDate[j + 1] = t;}}}foreach (string s in myDate){Console.WriteLine(s);}//将排好序的数写回到文件中FileStream fs1 = new FileStream("D:\\1.txt", FileMode.Open,FileAccess.ReadWrite);StreamWriter sw = new StreamWriter(fs1);for (int i = 0; i < myDate.Length - 1; i++){sw.Write(myDate[i]);sw.Write(",");}sw.Write(myDate[myDate.Length - 1]);sw.Close();fs1.Close();FileStream fs2 = new FileStream("D:\\1.txt", FileMode.Open, FileAccess.ReadWrite);StreamReader sr2 = new StreamReader(fs2);richTextBox2.Text = sr2.ReadToEnd();sr2.Close();fs2.Close();}private void button2_Click(object sender, EventArgs e){Random newRandom = new Random();//声明产生随机数对象FileInfo fi = new FileInfo("D:\\1.txt");using (StreamWriter sw = fi.AppendText()){//写入随机数for (int i = 0; i < 10; i++){sw.Write(',');sw.Write(newRandom.Next());}sw.Write(newRandom.Next());FileStream fs2 = new FileStream("D:\\1.txt", FileMode.Open, FileAccess.ReadWrite);StreamReader sr2 = new StreamReader(fs2);richTextBox2.Text = sr2.ReadToEnd();sr2.Close();fs2.Close();}}private void button3_Click(object sender, EventArgs e){this.Close();}}}运行结果(2)文本编辑器界面:源程序using System;using System.Collections.Generic; using ponentModel; using System.Data;using System.Drawing;using System.Text;using System.Windows.Forms;using System.IO;namespace 文本编辑器设计{public partial class Form3 : Form{public Form3(){InitializeComponent();}private void 新建ToolStripMenuItem_Click(object sender, EventArgs e) {textBox1.Clear();this.Text = "新建文件";}private void 打开ToolStripMenuItem_Click(object sender, EventArgs e) {textBox1.Select();}private void 剪切ToolStripMenuItem_Click(object sender, EventArgs e) {textBox1.Cut();}private void 粘贴ToolStripMenuItem_Click(object sender, EventArgs e) {textBox1.Paste();}private void 复制ToolStripMenuItem_Click(object sender, EventArgs e) {textBox1.Copy();}private void 红色ToolStripMenuItem_Click(object sender, EventArgs e) {textBox1.ForeColor=Color.Red;}private void 黑色ToolStripMenuItem_Click(object sender, EventArgs e) {textBox1.ForeColor = Color.Black;}}}运行结果:(3)文件查找界面:源程序:using System;using System.Collections.Generic; using ponentModel; using System.Data;using System.Drawing;using System.Text;using System.Windows.Forms;using System.IO;namespace 文本编辑器设计{public partial class Form4 : Form{public Form4(){InitializeComponent();}public void FindFile(string dir){DirectoryInfo Dir = new DirectoryInfo(dir);try{foreach (DirectoryInfo d in Dir.GetDirectories()) {FindFile(Dir + d.ToString() + "\\");}foreach (FileInfo D in Dir.GetFiles("*.doc")) {listBox1.Items.Add(Dir + D.ToString());}}catch (Exception e){MessageBox.Show(e.Message);}}private void button3_Click(object sender, EventArgs e){FindFile(textBox1.Text);}private void button2_Click(object sender, EventArgs e){this.Close();}private void button1_Click(object sender, EventArgs e){this.listBox1.Items.Clear();this.textBox1.Clear();}}}运行结果:(4)文件合并源程序:using System;using System.Collections.Generic;using ponentModel;using System.Data;using System.Drawing;using System.Text;using System.Windows.Forms;using System.IO;namespace 文本编辑器设计{public partial class Form1 : Form{public Form1(){InitializeComponent();}private void button1_Click(object sender, EventArgs e) {Form2 x = new Form2();x.Show();}private void button2_Click(object sender, EventArgs e) {Form3 y = new Form3();y.Show();}private void button3_Click(object sender, EventArgs e){Form4 z = new Form4();z.Show();}private void button4_Click(object sender, EventArgs e){FileStream fs1 = new FileStream("1.txt", FileMode.Open);StreamReader sr1 = new StreamReader(fs1);string text1 = sr1.ReadToEnd();fs1.Close();sr1.Close();FileStream fs2 = new FileStream("2.txt", FileMode.Open);StreamReader sr2 = new StreamReader(fs2);string text2 = sr2.ReadToEnd();fs2.Close();sr2.Close();using (StreamWriter sw = File.CreateText("3.txt")){sw.WriteLine(text1);sw.WriteLine(text2);sw.WriteLine(text1);sw.WriteLine(text2);MessageBox.Show("文件添加完毕!", "提示", MessageBoxButtons.OK, rmation);File.Delete("1.txt");File.Delete("2.txt");MessageBox.Show("文件删除完毕!", "提示", MessageBoxButtons.OK, rmation);sw.Close();}}}}运行结果:实验二 C#图形程序设计基础一:实验目的:1、熟悉VisualC#.NET的图形基础知识,绘图的基本知识2、学会GDI+基础知识3、建立画笔,画刷4、画图的方法及使用二:实验内容:1、使用图形方法,画出5条不同颜色的直线并形成一个多边形。
C语言编写的文本编辑器在现代的计算机应用领域中,文本编辑器是一个不可或缺的工具。
它们提供了一种方便的方式来编辑、查看和管理文本文件。
C语言作为一种高级编程语言,被广泛应用于软件开发领域。
本文将介绍如何使用C语言编写一个简单的文本编辑器。
一、概述文本编辑器是一种计算机程序,旨在帮助用户处理文本文件。
它们提供了一系列功能,如插入、删除、复制、粘贴和查找等,以便用户可以轻松编辑文本。
C语言作为系统级编程语言,具有高效的内存管理和强大的控制能力,非常适合编写文本编辑器。
二、设计思路在开始编写文本编辑器之前,需要明确其基本功能和设计思路。
一个简单的文本编辑器应具备以下功能:1. 新建、打开、保存文本文件;2. 插入、删除、复制、粘贴文本内容;3. 查找和替换文本内容;4. 撤销和重做操作。
基于以上功能,我们可以使用C语言的字符串处理函数和文件操作函数来实现文本编辑器。
三、核心代码下面是一个简化版本的C语言文本编辑器的核心代码示例:```c#include <stdio.h>#include <stdlib.h>#include <string.h>#define MAX_LENGTH 1000int main() {char buffer[MAX_LENGTH];FILE *file;char filename[100];int choice;printf("欢迎使用简单文本编辑器\n");while (1) {printf("\n1. 新建文件\n2. 打开文件\n3. 保存文件\n4. 插入文本\n5. 删除文本\n6. 复制文本\n7. 粘贴文本\n8. 查找文本\n9. 替换文本\n10. 撤销操作\n11. 重做操作\n12. 退出\n");printf("请输入选项:");scanf("%d", &choice);switch (choice) {case 1:printf("请输入文件名:"); scanf("%s", filename);file = fopen(filename, "w"); if (file == NULL) {printf("无法创建文件\n"); }break;case 2:printf("请输入文件名:"); scanf("%s", filename);file = fopen(filename, "r"); if (file == NULL) {printf("文件不存在\n"); }break;case 3:if (file == NULL) {printf("请先新建或打开文件\n");} else {fclose(file);printf("文件已保存\n");file = NULL;}break;case 4:if (file == NULL) {printf("请先新建或打开文件\n");} else {printf("请输入要插入的文本:"); fgets(buffer, MAX_LENGTH, stdin); fputs(buffer, file);fflush(file);}break;// 其他功能代码省略...case 12:if (file != NULL)fclose(file);printf("感谢使用简单文本编辑器,再见!\n");exit(0);default:printf("无效的选项\n");break;}}return 0;}```该代码演示了一个简单的文本编辑器,用户可以通过输入选项来执行各种功能。
实训题目:文本编辑器1 系统设计1.1 设计要求1.1.1 设计任务设计一个基于对话框的文本编辑器,实现文本的创建、编辑、显示及保存功能。
1.1.2 性能指标要求按照题目要求完成程序源码编写、调试及关键代码注释。
能够设置字体格式。
1.2 设计思路及设计框图1.2.1设计思路通过Visual C++6.0内自带的控件进行编程,产生一个基于对话框的文本编辑器。
该编辑器带有菜单栏、编辑区。
(1)文件模块:提供保存、另存为、打开、退出功能。
(2)编辑模块:提供撤销、剪切、复制、粘贴、清空、全选功能。
(3)格式模块:提供设置字体、背景颜色功能。
(4)帮助模块:版权声明。
1.2.2总体设计框图2 各个模块程序的设计及相应流程图2.1 新建工程通过Visual C++6.0内自带的控件进行编程,产生一个基于对话框的文本编辑器。
2.2图标设计设计IDR_MAINFRAME图案,修改后如下2.3 菜单栏设计右击VC6.0菜单栏Insert下的Resource,插入一个菜单栏,如下。
这里已经建好。
只是演示步骤。
以下为菜单相关名称与函数下拉菜单名命令名命令ID 对应消息函数名文件(&F) 打开(&O)...\tCtrl+O ID_FILE_OPEN OnFileOpen保存(&S)\tCtrl+S ID_FILE_SA VE OnFileSave另存为(&A)...ID_FILE_SA VE_AS OnFileSaveAs退出(&X)ID_APP_EXIT OnAppExit编辑(&E) 撤消(&U)\tCtrl+Z ID_EDIT_UNDO OnEditUndo 剪切(&T)\tCtrl+X ID_EDIT_CUT OnEditCut复制(&C)\tCtrl+C ID_EDIT_COPY OnEditCopy 粘贴(&P)\tCtrl+V ID_EDIT_PASTE OnEditPaste 清空(&R)ID_EDIT_CLEAR OnEditClear全选(&A)\tCtrl+A ID_EDIT_SELECTALLOnEditSelectall格式(&S)字体(&F)...ID_SET_FONT OnSetFont背景颜色(&B)...ID_SET_BACKCOLOROnSetBackcolor帮助(&H)关于文档编辑器(&A)...IDS_ABOUTBOX OnAboutbox 快捷键工程内容如下2.4 菜单栏载入打开IDD_WENBEN_DIALOG对话框属性,在常规标签页下的菜单对话框内添加菜单栏的ID,即IDR_MENU1。
C语⾔实现简易⽂本编辑器本程序要求完成⼀个简易⽂本编辑器,能够完成⽂本的录⼊、编辑、删除、查找,并能够完成⽂件的存取。
在⽂本编辑软件中把⽤户输⼊的所有⽂本内容作为⼀个字符串。
虽然各种⽂本编辑软件的功能有强弱差别,但是基本操作都包括串的输⼊、修改、删除(包括整⾏删除和⼀⾏中的⼦串删除)、查找、输出等。
通过分析,系统应该包括以下功能:1、具有简单的⽂字或图形菜单界⾯2、能实现串或⽂本块的查找、替换、删除、插⼊、移动操作。
3、能实现⽂本⽂件的存盘和读取功能。
4、具有友好的界⾯和较强的容错能⼒设计思路1、采⽤的逻辑结构⽂本编辑器主要是针对⽂本进⾏编辑,⽂本的操作就是对字符的操作。
⽂本编辑器可以从⾏、列两个⽅向进⾏编辑。
每⼀⾏可以看成⼀个线性表,线性表是⼀种线性结构,线性结构的特点是数据元素之间为线性关系,数据元素“⼀个接⼀个的排列”。
在⼀个线性表中数据元素的类型是相同的,由于每⼀⾏可以存储的最⼤字数是相同的,⾏⽅向所有线性表的最⼤长度可以设置成相同的。
⾏与⾏之间的关系也可以看成⼀个线性表。
2、采⽤的存储结构线性表的存储分为两种:顺序存储和链式存储。
顺序存储是指在内存中⽤地址连续的⼀块存储空间顺序存放线性表的各元素,⽤这种存储形式存储的线性表称为顺序表。
在程序设计语⾔中,⼀维数组在内存中占⽤的存储空间就是⼀组连续的存储区域,因此,⽤⼀维数组来表⽰顺序表的数据存储区域是再合适不过的。
链式存储是通过-组任意的存储单元来存储线性表中的数据元素的,为建⽴数据元系之间的线性关系,对每个数据元素除了存放数据元素⾃⾝的信息之外,还需要和⼀起存放其后继或前驱所在的存储单元的地址,这两部分信息组成⼀个“结点”,每个元素都如此。
存放数据元素信息的称为数据域,存放其前驱或后继地址的称为指针域。
只有⼀个存储单元地址的为单链表,有两个存储单元地址的为双链表。
考虑到实际的功能需求,每⾏的线性表可以⽤顺序存储⽅式,每个字符是⼀个节点。
/* A Screen Editer Subsystem */#define TURBOC#include <stdio.h>#include <dos.h>#include <string.h>#include <bios.h>#include <conio.h>#define BUF_SIZE 32000#define LINE_LEN 79-2#define MAX_LINES 24-1#define KILL_BUF_SIZE 4*LINE_LEN/***********************************************************/char buf[BUF_SIZE];char *curloc,*endloc;int scrnx,scrny;char killbuf[KILL_BUF_SIZE];char *helpline="F1:save F2:load F3:find F4:replace ^K:kill line ^Y:Yank ^Z:qiut"; /*************************************************************/ void edit(char *fname),help(void);void gotoxy(int x,int y),clrline(int y);void edit_clr_col(int x,int y),clrscr(void);void printline(char *p),delete_char(void);void search(void),kill_line(void);void scrolldn(int x,int y);void scrollup(int topx,int topy,int endx,int endy);void upline(void);void downline(void),left(void),right(void);void display_scrn(int x,int y,char *p);void pagedown(void),pageup(void),replace(void);void home(void),gotoend(void),yank(void);int load(char *fname),save(char *fname);void edit_gets(char *str);void draw_border(int,int,int,int,int);/***************************************************/main(int argc,char *argv[]){union REGS r;char fname[80];if(argc<2){draw_border(0,0,78,24,0x1f);draw_border(20,12,60,14,0x2f);gotoxy(20,11);printf("\7FILE NAME:");gotoxy(21,13);gets(fname);edit(fname);}if(argc==2){strupr(argv[1]);if(strstr(argv[1],".EXE")||strstr(argv[1],".COM")||\strstr(argv[1],".OBJ")||strstr(argv[1],".LIB")){printf("\7Can't edit file :%s",argv[1]);exit(1);}else edit(argv[1]);}r.h.ah=6;r.h.al=0;r.h.ch=0;r.h.cl=0;r.h.dh=24;r.h.dl=79;r.h.bh=7;int86(0x10,&r,&r);gotoxy(1,1);}/******************************************************************/ void edit(char *fname){union k{char ch[2];unsigned i;}key;char name[80];/* try to load the file */if(!load(fname))curloc=endloc=buf;strcpy(name,fname);/* set initial values to X,Y coordinate vars */scrnx=scrny=0;display_scrn(0,0,curloc);help();gotoxy(1,1);/* editer main loop . */do{#ifdef TURBOCkey.i=bioskey(0);#endifif(!key.ch[0]){switch(key.ch[1]){case 59: /*F1 :save file */save(name);break;case 60: /*F2: load file */clrline(MAX_LINES);gotoxy(1,MAX_LINES);printf("Enter filename :");edit_gets(name);strupr(name);if(strstr(name,".EXE")||strstr(name,".COM")||\strstr(name,".OBJ")||strstr(name,".LIB")){gotoxy(1,MAX_LINES);printf("\7Can't edit file: %s",name);getch();help();break;}if( * name) load(name);help();display_scrn(0,0,curloc);scrnx=scrny=0;break;case 61:search();break;case 62:replace();break;case 71:home();break;case 79:gotoend();break;case 75: /*left*/left();break;case 77:right();break;case 72:upline();break;case 80:downline();break;case 73:pageup();break;case 81:pagedown();break;case 83: /*Del*/if(curloc<endloc) delete_char();break;}if(curloc<buf){scrnx=scrny=0;curloc=buf;}gotoxy(scrnx+1,scrny+1); /*postion cursor */ }else{switch(key.ch[0]){case '\r':/*see if buffer is full */if(endloc==buf+BUF_SIZE-2) break;/* move contents of file below current location down one byte to make room for the RETURN.*/ memmove(curloc+1,curloc,endloc-curloc+1);*curloc=key.ch[0]; /*put RETURN in file *//*clear rest of line */edit_clr_col(scrnx,scrny);scrnx=0;scrny++;/*move text on screen down */if(scrny==MAX_LINES-1){/*at bottom of page */scrny=MAX_LINES-2;scrollup(1,1,LINE_LEN,scrny+1);}else scrolldn(scrnx+1,scrny+1);gotoxy(scrnx+1,scrny+1);printline(curloc);endloc++;/* advance the end of file pointer */ break;case '\b':if(curloc==buf) break;left();delete_char();break;case 11:kill_line();break;case 25:yank();break;case 26:clrline(MAX_LINES);gotoxy(1,MAX_LINES);printf("If saved file,press[Y]exit\7");if(tolower(getch())=='y') goto end;help();break;default: /* enter keystroke into file *//*see if buf is full */if(endloc==buf+BUF_SIZE-2) break;/*can't type past end of line */if(scrnx==LINE_LEN) break;memmove(curloc+1,curloc,endloc-curloc+1); *curloc=key.ch[0];putch(*curloc);gotoxy(scrnx+1,scrny+1);printline(curloc+1);curloc++;endloc++;}gotoxy(scrnx+1,scrny+1);}}while(1);end:printf("\n");}/**************************************************************************** Display a line pointed to by p.****************************************************************************/ void printline(register char *p){register int i;i=scrnx+1;while(*p!='\r'&&*p&&i<LINE_LEN){putch(*p);p++;i++;}}/**************************************************************************** Insert previously killled line.****************************************************************************/ void yank(void){char *p;p=killbuf;while(*p){memmove(curloc+1,curloc,endloc-curloc+1);*curloc=*p;if(scrnx<LINE_LEN){putch(*curloc);scrnx++;}endloc++;p++;}}/*******************************************************//* Delete the line at the current location */void kill_line(void){register int i;char *p,*killbufptr;if(*curloc=='\r'){delete_char();return;}edit_clr_col(scrnx,scrny); /*clear to CR *//* find out hoe many characters are in the line */p=curloc;i=0;killbufptr=killbuf;while(*p!='r'&&p<endloc){i++;*killbufptr=*p;p++;if(killbufptr<killbuf+KILL_BUF_SIZE-2) killbufptr++;}*killbufptr='\0';/* remove the line */memmove(curloc,curloc+i,endloc-curloc);endloc-=i;}/*********************************************************************** Global search and replace***********************************************************************/ void replace(void){register int len1;char str1[80],str2[80];char *p,*p2;clrline(MAX_LINES);gotoxy(1,MAX_LINES);printf("enter string to replace :");edit_gets(str1);clrline(MAX_LINES);gotoxy(1,MAX_LINES);printf("enter replacement:");edit_gets(str2);p=curloc;len1=strlen(str1);while(*str1){/*search for the string */while(*p && strncmp(str1,p,len1)) p++; if(!*p){clrline(MAX_LINES);gotoxy(1,MAX_LINES);printf("No found string %s",str1); getch();help();break;} /* not found *//* remove old string */memmove(p,p+len1,endloc-p);endloc-=len1;/*insert new string */p2=str2;while(*p2){memmove(p+1,p,endloc-p+1);*p=*p2;p++;endloc++;p2++;}}clrscr();/* find location of top screen */p=curloc;for(len1=scrny;len1>=0&&p<buf;){p--;if(*p=='r') len1--;}if(*p=='r') p++;/* redisplay current screen */display_scrn(0,0,p);help();}void delete_char(void){gotoxy(scrnx+1,scrny+1);if(*curloc=='r'){scrollup(1,scrny+1+1,LINE_LEN,MAX_LINES-1);memmove(curloc,curloc+1,endloc-curloc);endloc--;display_scrn(scrnx,scrny,curloc);help();}else{memmove(curloc,curloc+1,endloc-curloc);endloc--;printline(curloc);printf("");}}/************************************************************************* Display help line.*************************************************************************/ void help(void){gotoxy(1,MAX_LINES);printf(helpline);}/************************************************************************* Move cuuren location left*************************************************************************/ void left(void){if(curloc==buf) return;scrnx--;if(scrnx<0){scrnx=0;upline(); /*go up to next line *//* find end of line */while(*curloc!='r'){curloc++;scrnx++;}}else curloc--;}/********************************************************************** Move current position right.**********************************************************************/ void right(void){if(curloc+1>endloc) return;scrnx++;/* if at the end of line,go to the next one. */if(scrnx>LINE_LEN||*curloc=='\r'){scrnx=0;scrny++;if(scrny==MAX_LINES-1) /* at end of screen */{scrny=MAX_LINES-2;downline();/* move cursor and current loc to start of new line */curloc--;while(*curloc!='\r') curloc--;curloc++;scrnx=0;}else curloc++;}else curloc++;}/**********************************************************************/ void search(void){char str[80];register char *p;int len,i;clrline(MAX_LINES);gotoxy(1,MAX_LINES);printf("search string :");edit_gets(str);if(! *str){help();return;}p=curloc;len=strlen(str);while(*p&&strncmp(str,p,len)) p++;if(! *p){gotoxy(1,MAX_LINES);printf("\7No found string %s!",str);getch();help();return;} /* not found */i=0;while(p>buf&&*p!='\r'){p--;i++;}p++;i--;/* reposition curren location to start of match */curloc=p+i;scrnx=i;scrny=0;clrscr();display_scrn(0,0,p);help();}/***************************************************************************** Move up a line.*****************************************************************************/ void upline(void){register int i;char *p;if(curloc==buf)return;p=curloc;if(*p=='\r') p--;for(;*p!='\r'&&p<buf;p--);if(*p=='\r')return;curloc=p;curloc--;i=scrnx; /* save X coordinate *//* find start of next line */while(*curloc!='\r'&&curloc>buf) curloc--;scrny--;scrnx=0;curloc++;/* if at top of screen ,must stop */if(scrny<0){scrolldn(1,1);scrny=0;gotoxy(1,1);printline(curloc);}while(i&&*curloc!='\r'){curloc++;scrnx++;i--;}}/*************************************************************************** Move down one line,keep previous scrnx location if possible**************************************************************************/ void downline(void){register int i;char *p;i=scrnx;p=curloc;while(*p!='\r'&&p<endloc) p++;if(p==endloc) return;p++;curloc=p;scrny++;scrnx=0;if(scrny==MAX_LINES-1){scrny=MAX_LINES-2;scrollup(1,1,LINE_LEN,MAX_LINES-1);gotoxy(scrnx+1,scrny+1);printline(curloc);}while(i&& *curloc!='\r' && curloc<endloc){curloc++;scrnx++;i--;}}/**************************************************************************** Display a screen full of text (up to 24 lines)***************************************************************************/ void display_scrn(int x,int y,char *p){register int i,j;gotoxy(x+1,y+1);textcolor(WHITE);textbackground(BLUE);i=0;while(y<MAX_LINES-1&&*p){switch(*p){case '\r': printf("\n");y++;gotoxy(1,y+1);i=0;break;case '\x09':for(j=0;j<8;j++){printf(" ");i++;}default:if(i<LINE_LEN) putch(*p);i++;}p++;}}/**************************************************************************** Page down MAX_LINES lines*****************************************************************************/ void pagedown(void){register int i;clrscr();for(i=0;i<MAX_LINES&&curloc<endloc;){if(*curloc=='\r') i++;curloc++;}help();scrnx=0;scrny=0;display_scrn(0,0,curloc);}/*************************************************************************** Page up MAX_LINES line***************************************************************************/ void pageup(void){register int i;clrscr();for(i=0;i<MAX_LINES&&curloc>buf;){if(*curloc=='\r') i++;curloc--;}scrnx=scrny=0;display_scrn(0,0,curloc);help();}/************************************************************************** Go to the end of the file**************************************************************************/ void gotoend(void){int i;char *p;p=curloc;for(i=scrnx;*p!='\r'&&p<endloc;){scrnx++;p++;i++;}gotoxy(scrnx+1,scrny+1);curloc=p;}/**************************************************************************** Load a file****************************************************************************/ int load(char *fname){FILE *fp;char ch,*p;int i;draw_border(0,0,78,24,0x2f);clrscr();if((fp=fopen(fname,"rb"))==NULL) return 0;gotoxy(1,1);p=buf;while(!feof(fp)&&p!=buf+BUF_SIZE-2){ch=getc(fp);if(ch=='\x09')for(i=0;i<8;i++,p++) *p='\x20';else if(ch!='\n'&&ch!=EOF){*p=ch;p++;}}*p='\0';fclose(fp);curloc=endloc=p;clrscr();curloc=buf;help();scrnx=scrny=0;display_scrn(0,0,curloc);}/****************************************************************************** ***Go to top the file******************************************************************************/ void home(void){curloc-=scrnx;scrnx=0;gotoxy(scrnx+1,scrny);}/****************************************************************************** Save a file*****************************************************************************/ int save(char *fname){int i;FILE *fp;char *p,name[80];if(!*fname){clrline(MAX_LINES);gotoxy(1,MAX_LINES);printf("filename:");gets(name);}else strcpy(name,fname);if((fp=fopen(name,"wb"))==NULL) return 0;p=buf;while(p!=endloc){if(*p!='\r')putc(*p,fp);else{putc('\r',fp);putc('\n',fp);}p++;}fclose(fp);clrline(MAX_LINES);printf("file %s already saved.",name);help();return 1;}/****************************************************************************** Read a string from the keyboard*****************************************************************************/ void edit_gets(char *str){char *p;p=str;for(;;){*str=getch();if(*str=='\r'){*str='\0';return;}if(*str=='\b'){if(str>p){str--;putch('\b');putch(' ');putch('\b');}}else{putch(*str);str++;}}}/****************************************************************************** *Read and save cursor coordinates******************************************************************************/ void cursor_pos(void){union REGS i,o;i.h.ah=3;int86(16,&i,&o);}/****************************************************************************** **Send cursor to specified X,Y(0,0 is upper left corner).*****************************************************************************/ void gotoxy(int x,int y){union REGS i;i.h.dh=y;i.h.dl=x;i.h.ah=2;i.h.bh=0;int86(16,&i,&i);}/***************************************************************************** Clear entire line given its Y coordinate*****************************************************************************/ void clrline(int y){register int i;gotoxy(1,y);for(i=0;i<LINE_LEN;i++) putch(' ');textcolor(WHITE);textbackground(BLUE);}/**************************************************************************** Clear to end of specified line.****************************************************************************/ void edit_clr_col(int x,int y){char *p;p=curloc;gotoxy(x+1,y+1);for(;x<LINE_LEN&&*p!='\r'&&*p;x++,p++){printf(" ");}}/**************************************************************************** Clear the screen.****************************************************************************/ void clrscr(void){union REGS r;r.h.ah=6;r.h.al=0;r.h.ch=1;r.h.cl=1;r.h.dh=MAX_LINES-1;r.h.dl=LINE_LEN;r.h.bh=0x1f;int86(0x10,&r,&r);}/*************************************************************************** Scroll down the screen.***************************************************************************/ void scrolldn(int x,int y){union REGS r;r.h.ah=7;r.h.al=1;r.h.ch=y;r.h.cl=x;r.h.dh=MAX_LINES-1;r.h.dl=LINE_LEN;r.h.bh=0x1f;int86(0x10,&r,&r);}/**************************************************************************** Srcoll up the screen.****************************************************************************/ void scrollup(int topx,int topy,int endx,int endy){union REGS r;r.h.ah=6;r.h.al=1;r.h.ch=topy;r.h.cl=topx;r.h.dh=endy;r.h.dl=endx;r.h.bh=0x1f;int86(0x10,&r,&r);}/**************************************************************************/ void draw_border(int beginx,int beginy,int endx,int endy,int attr){int i;union REGS r;r.h.ah=6;r.h.al=0;r.h.ch=beginy;r.h.cl=beginx;r.h.dh=endy;r.h.dl=endx+1;r.h.bh=attr;int86(0x10,&r,&r);for(i=beginx;i<endx;i++){ gotoxy(i,beginy);putchar(196);gotoxy(i,endy);putchar(196);}for(i=beginy;i<=endy;i++){gotoxy(beginx,i);putchar(179);gotoxy(endx,i);putchar(179);}gotoxy(beginx,beginy);putchar(218);gotoxy(beginx,endy);putchar(192);gotoxy(endx,beginy);putchar(191);gotoxy(endx,endy);putchar(217);}。
实验3 文本编辑器【实验目的】⏹进一步实践windows窗口程序开发的流程;⏹掌握并熟练使用RichTextBox、Button、MenuTrip控件。
【实验环境】Visual Studio 2005(或更高版本)【实验内容】设计一个基于RichTextBox的文本编辑器,要求实现文件打开、保存、字体和颜色修改、字符查找和替换功能,鼓励扩展其他功能。
【实验结果】文件菜单:打开程序编辑文本->文件->保存保存结果:编辑文本:文件->打开(文件已修改打开询问保存)点击“是”->继续打开此文件(点击“取消”或者关闭提示则不执行打开“否”则不保存)打开后:(上次打开操作保存结果在本次打开中体现)文件->另存为另存为结果:编辑文本文件->退出(退出提示保存)点击“否”(点击“取消”或者关闭提示则不执行退出“是”则保存)设置文件打开方式为本实验程序出”)不修改文本文件->退出(由于文件没有修改不提示保存直接退出关闭窗口同理)编辑菜单:编辑->查找(不演示撤销等操作、没有查找内容“查找下一个”处于禁用)输入查找内容点击“查找下一个”:再次点击“查找下一个”:打钩区分大小写选择方向向上两次点击“查找下一个”:取消打钩区分大小写编辑->查找(没有查找内容和替换“查找下一个”“替换”...处于禁用)打钩区分大小写输入查找内容和替换内容点击两次替换取消打钩区分大小写点击全部替换格式菜单:格式->字体确定后:格式->颜色确定后:格式->对齐方式全选格式->对齐方式->右对齐(不演示居中)帮助->关于【实验核心代码】Form1(主窗口):using System;using System.Collections.Generic;using ponentModel;using System.Data;using System.Drawing;using System.Linq;using System.Text;using System.Windows.Forms;namespace FileEdit{public partial class Form1 : Form{private string filename;private RichTextBox rtb = new RichTextBox();public Form1(string path){InitializeComponent();filename = path;}private void 打开OToolStripMenuItem_Click(object sender, EventArgs e){if (!richTextBox1.Text.Equals(rtb.Text)){DialogResult result = MessageBox.Show("是否将更改保存到" + filename, "", MessageBoxButtons.YesNoCancel, MessageBoxIcon.Question);if (result == DialogResult.Yes)this.保存SToolStripMenuItem_Click(sender, e);else if (result == DialogResult.Cancel)return;}OpenFileDialog open = new OpenFileDialog();open.Filter = "Word文档(*.rtf)|*.rtf";if (open.ShowDialog() == DialogResult.OK){richTextBox1.LoadFile(open.FileName, RichTextBoxStreamType.RichText);rtb.Text = richTextBox1.Text;filename = open.FileName;this.Text = filename.Substring(stIndexOf('\\') + 1) + " - 文本编辑器";}}private void 复制CToolStripMenuItem_Click(object sender, EventArgs e){richTextBox1.Copy();}private void 剪切ToolStripMenuItem_Click(object sender, EventArgs e){richTextBox1.Cut();}private void 粘贴VToolStripMenuItem_Click(object sender, EventArgs e){richTextBox1.Paste();}private void 保存SToolStripMenuItem_Click(object sender, EventArgs e){if (filename == "无标题")?????????????{SaveFileDialog dlgSave=new SaveFileDialog();dlgSave.InitialDirectory="c:\tmp";dlgSave.Filter = "Word文档(*.rtf)|*.rtf";dlgSave.Title="保存我的文件";if(dlgSave.ShowDialog()==DialogResult.OK){filename=dlgSave.FileName;richTextBox1.SaveFile(filename,?RichTextBoxStreamType.RichText);}}else{richTextBox1.SaveFile(filename, RichTextBoxStreamType.RichText);}rtb.Text = richTextBox1.Text;}private void 新建NToolStripMenuItem_Click(object sender, EventArgs e){if (!richTextBox1.Text.Equals(rtb.Text)){DialogResult result = MessageBox.Show("是否将更改保存到" + filename, "", MessageBoxButtons.YesNoCancel, MessageBoxIcon.Question);if (result == DialogResult.Yes)this.保存SToolStripMenuItem_Click(sender, e);else if (result == DialogResult.Cancel)return;}richTextBox1.Text = "";filename = "无标题";this.Text = filename + " - 文本编辑器";}private void 另存为ToolStripMenuItem_Click(object sender, EventArgs e) {SaveFileDialog dlgSave = new SaveFileDialog();dlgSave.InitialDirectory = "c:\tmp";dlgSave.Filter = "Word文档(*.rtf)|*.rtf";dlgSave.Title = "保存我的文件";if (dlgSave.ShowDialog() == DialogResult.OK){filename = dlgSave.FileName;richTextBox1.SaveFile(filename, RichTextBoxStreamType.RichText);rtb.Text = richTextBox1.Text;}}private void 撤销ToolStripMenuItem_Click(object sender, EventArgs e) {richTextBox1.Undo();}private void 查找ToolStripMenuItem_Click(object sender, EventArgs e) {Formcz cz = new Formcz(richTextBox1);cz.Owner = this;cz.Show();}private void 替换ToolStripMenuItem_Click(object sender, EventArgs e) {Formth th = new Formth();th.Textbox = richTextBox1;th.Owner = this;th.Show();}private void 字体ToolStripMenuItem_Click(object sender, EventArgs e) {FontDialog dlgFont = new FontDialog();dlgFont.ShowColor = true;dlgFont.ShowApply = true;if (richTextBox1.SelectionLength > 0){dlgFont.Font = richTextBox1.SelectionFont;dlgFont.Color = richTextBox1.SelectionColor;}else{dlgFont.Font = richTextBox1.Font;dlgFont.Color = richTextBox1.ForeColor;}if (dlgFont.ShowDialog() == DialogResult.OK){if (richTextBox1.SelectionLength > 0){richTextBox1.SelectionFont = dlgFont.Font;richTextBox1.SelectionColor = dlgFont.Color;}else{richTextBox1.Font = dlgFont.Font;richTextBox1.ForeColor = dlgFont.Color;}}}private void 颜色ToolStripMenuItem_Click(object sender, EventArgs e) {ColorDialog dlgColor = new ColorDialog();if (richTextBox1.SelectionLength > 0)dlgColor.Color = richTextBox1.SelectionColor;elsedlgColor.Color = richTextBox1.ForeColor;if (dlgColor.ShowDialog() == DialogResult.OK){if (richTextBox1.SelectionLength > 0)richTextBox1.SelectionColor = dlgColor.Color;elserichTextBox1.ForeColor = dlgColor.Color;}}private void 左对齐ToolStripMenuItem_Click(object sender, EventArgs e)右对齐ToolStripMenuItem.Checked = false;居中ToolStripMenuItem.Checked = false;richTextBox1.SelectionAlignment = HorizontalAlignment.Left;}private void 右对齐ToolStripMenuItem_Click(object sender, EventArgs e){左对齐ToolStripMenuItem.Checked = false;居中ToolStripMenuItem.Checked = false;richTextBox1.SelectionAlignment = HorizontalAlignment.Right;}private void 居中ToolStripMenuItem_Click(object sender, EventArgs e){左对齐ToolStripMenuItem.Checked = false;右对齐ToolStripMenuItem.Checked = false;richTextBox1.SelectionAlignment = HorizontalAlignment.Center;}private void 关于ToolStripMenuItem1_Click(object sender, EventArgs e){MessageBox.Show("作者:软件1201 58号林鑫杰\n编写时间:2014年9月28", "关于", MessageBoxButtons.OK, rmation);}private void Form1_Load(object sender, EventArgs e){richTextBox1.Text = "";rtb.Text = richTextBox1.Text;if (filename == null){filename = "无标题";this.Text = filename + " - 文本编辑器";}else{richTextBox1.LoadFile(filename, RichTextBoxStreamType.RichText);rtb.Text = richTextBox1.Text;this.Text = filename.Substring(stIndexOf('\\') + 1) + " - 文本编辑器";}}private void Form1_FormClosing(object sender, FormClosingEventArgs e)if (!richTextBox1.Text.Equals(rtb.Text)){DialogResult result = MessageBox.Show("是否将更改保存到" + filename, "退出", MessageBoxButtons.YesNoCancel, MessageBoxIcon.Question);if (result == DialogResult.No)e.Cancel = false;else if (result == DialogResult.Yes)this.保存SToolStripMenuItem_Click(sender, e);}}private void 退出ToolStripMenuItem_Click(object sender, EventArgs e){this.Close();}private void 全选ToolStripMenuItem_Click(object sender, EventArgs e){richTextBox1.SelectAll();}}}Form2(查找窗口):using System;using System.Collections.Generic;using ponentModel;using System.Data;using System.Drawing;using System.Linq;using System.Text;using System.Windows.Forms;namespace FileEdit{public partial class Formcz : Form{private RichTextBox textbox;private static int i;private static int j;public Formcz(RichTextBox textbox){InitializeComponent();this.textbox = textbox;j = textbox.Text.Length;i = 0;}private void button1_Click(object sender, EventArgs e){if (radioButton1.Checked){if (checkBox1.Checked)j = textbox.Find(textBox1.Text, 0, j, RichTextBoxFinds.Reverse | RichTextBoxFinds.MatchCase);elsej = textbox.Find(textBox1.Text, 0, j, RichTextBoxFinds.Reverse | RichTextBoxFinds.WholeWord);}else{if (checkBox1.Checked)i = textbox.Find(textBox1.Text, i, RichTextBoxFinds.MatchCase);elsei = textbox.Find(textBox1.Text, i, RichTextBoxFinds.WholeWord);}if (i == -1)i = 0;else{i += textBox1.Text.Length;textbox.Focus();}if (j <= 0)j = textbox.Text.Length;elsetextbox.Focus();}private void button2_Click(object sender, EventArgs e){this.Close();}private void textBox1_TextChanged(object sender, EventArgs e){if (this.textBox1.Text != "")this.button1.Enabled = true;elsethis.button1.Enabled = false;}private void radioButton2_CheckedChanged(object sender, EventArgs e){if (radioButton2.Checked == true)radioButton2.Checked = false;elseradioButton1.Checked = true;j = textbox.Text.Length;i = 0;}private void radioButton2_CheckedChanged_1(object sender, EventArgs e){j = textbox.Text.Length;i = 0;}}}Form3(替换窗口):using System;using System.Collections.Generic;using ponentModel;using System.Data;using System.Drawing;using System.Linq;using System.Text;using System.Windows.Forms;namespace FileEdit{public partial class Formth : Form{private RichTextBox textbox;public RichTextBox Textbox{get { return this.textbox; }set { this.textbox = value; }}private int i;public Formth(){InitializeComponent();}private void button1_Click(object sender, EventArgs e){if (checkBox1.Checked)i = textbox.Find(textBox1.Text, i, RichTextBoxFinds.MatchCase);elsei = textbox.Find(textBox1.Text, i, RichTextBoxFinds.None);if (i == -1)i = 0;else{i += textBox1.Text.Length;textbox.Focus();}}private void button2_Click(object sender, EventArgs e){if (checkBox1.Checked)i = textbox.Find(textBox1.Text, i, RichTextBoxFinds.MatchCase);elsei = textbox.Find(textBox1.Text, i, RichTextBoxFinds.None);if (i == -1)i = 0;else{textbox.SelectedText = textBox2.Text;i += textBox1.Text.Length;textbox.Focus();}}private void button3_Click(object sender, EventArgs e){while (true){if (checkBox1.Checked)i = textbox.Find(textBox1.Text, i, RichTextBoxFinds.MatchCase);elsei = textbox.Find(textBox1.Text, i, RichTextBoxFinds.None);if (i == -1){MessageBox.Show("已替换到文档的结尾!", "替换结束");i = 0;break;}else{textbox.SelectedText = textBox2.Text;i += textBox1.Text.Length;textbox.Focus();}}}private void button4_Click(object sender, EventArgs e){this.Close();}private void textBox1_TextChanged(object sender, EventArgs e){if(this.textBox1.Text!="")this.button1.Enabled = true;elsethis.button1.Enabled = false;}private void textBox2_TextChanged(object sender, EventArgs e){if (this.textBox1.Text != ""){this.button2.Enabled = true;this.button3.Enabled = true;}else{this.button2.Enabled = false;this.button3.Enabled = false;}}}}注意:以上是我们实验报告的主要内容代码部分每位同学请保存在一个文本文档或一个文件夹内(以后的实验文件结构会比本次试验复杂时)以后每次试验的每位同学都需要提交一个文件夹,该文件夹要求以“学号+姓名+实验n”命名如:,顺序格式都不能乱文件夹中需包含如下内容:文件夹:学号+姓名+实验n+实验源程序实验报告:学号+姓名+实验n+实验报告.doc实验代码:学号+姓名+实验n+实验核心代码.txt如图所示:顺序格式都不能乱!!。
吉林电子信息职业技术学院JiLin Technical College of Electronic Information课程实训课程名称:_________ 《C#.NET》 ___________指导教师:____________________________________ 实训时间:___________________________________吉林电子信息职业技术学院吉林电子信息职业技术学院课程实训任务书姓名:院(系):计算机系专业:软件技术班级:10软件任务起至日期:综合实训题目:“记事本”的文本编辑器已知技术参数和设计要求:应用环境:Win dows Server 2000/2003/XPSQL Server 2005开发环境:VS2005应用模式:B/S设计要求:按题目要求完成数据库设计、系统功能设计、界面设计。
(1)能够实现基本的文本文件读取、保存、设置字体等功能。
(2)具有菜单、工具栏和状态栏。
(3)实现其它相关功能(如字体、剪切板的操作,查找、打印预览等功能)(4)实现多文档界面工作量:记事本的程序测试,修改,以及添加。
工作计划安排:1项目培训、选题、准备开发环境0.5天2 项目设计、制作2天3 测试、完善0.5天4 完成报告1天同组实训者及分工:同组实训者:本人完成工作如下:记事本的代码修改以及添加测试。
指导教师签字月日年教研室主任意见:教研室主任签字年月日*注:此任务书由课程设计指导教师填写。
综合评语:成绩评定:指导教师签字 ________________________ 年教研室主任意见:教研室主任签字 _______________________系部审核盖章: 教务处批准盖章:课程实训用纸第1章问题描述(1 )能够实现基本的文本文件读取、保存、设置字体等功能。
(2) 具有菜单、工具栏和状态栏。
(3) 实现其它相关功能(如字体、剪切板的操作,查找、打印预览等功能) (4) 实现多文档界面第2章总体设计第3章界面设计1 •文件操作:包括文件的新建、打开、保存、另存为、页面设置、打印及退 出。
/*文本编辑器editor源代码*/#include <stdio.h>#include <conio.h>#include <bios.h>#include <math.h>#define LEFT 0x4b00 /*←:光标左移*/#define RIGHT 0x4d00 /*→:光标右移*/#define DOWN 0x5000 /*↓键:光标下移*/#define UP 0x4800 /*↑键:光标上移*/#define ESC 0x011b /*ESC键:取消菜单打开操作*/#define ENTER 0x1c0d /*回车键:换行*/#define DEL 21248 /*DEL键:删除当前字符*/#define BACK 3592 /*BackSpace键:删除当前光标位置前一个字符*/#define CL 29440 /*ctrl+←键:从右至左,选定文本*/#define CR 29696 /*ctrl+→键:从左到右,选定文本*/#define Cc 11779 /*ctrl+c键:将选定文本,复制一份到剪贴板中*/#define Cv 12054 /*ctrl+v键:将剪贴板中的内容复制到当前位置*/#define Cx 11544 /*ctrl+x键:对选定文本,执行剪切操作*/#define F1 15104 /*F1键:打开文件菜单*/#define F2 15360 /*F2键:打开编辑菜单*/#define F3 15616 /*F3键:打开帮助菜单*/#define F10 17408 /*F10键:进入文本快速预览模式*/int value,backup,NUM;/*value保存有值数组元素的最大下标值,backup保存value的副本,NUM保存当前行中的用户输入的字符个数*/typedef struct record{char ch; /*保存一字符*/int col, line; /*x轴和y轴坐标*/}record;record r[500]; /*定义一个有500个元素的结构体数组,保存选定的文本字符的属性*/typedef struct node /*定义保存行中的单个字符的结构*/{char ch; /*数据域:保存一字符*/struct node *next; /*指针域:指向下一个结点的指针*/}node;/*由此类型节点构成的单链表,命名为:列单链表*/typedef struct Hnode /*定义保存所有列单链表首节点的指针的结构*/{node *next; /*指向列单链表的首节点的地址*/struct Hnode *nextl; /*指向下一个节点的指针*/}Hnode;/*由此类型节点构成的单链表,命名为:行单链表*/void drawmain() /*画主窗口函数*/{int i,j;gotoxy(1,1); /*在文本窗口中设置光标至(1,1)处*/textbackground(7); /*选择新的文本背景颜色,7为LIGHTGRA Y淡灰色*/textcolor(0); /*在文本模式中选择新的字符颜色0为BLACK黑*/insline(); /*在文本窗口的(1,1)位置处中插入一个空行*/for(i=1;i<=24;i++){gotoxy(1,1+i); /*(x,y)中x不变,y++*/cprintf("%c",196); /*在窗口左边输出-,即画出主窗口的左边界*/gotoxy(80,1+i);cprintf("%c",196); /*在窗口右边,输出-,即画出主窗口的右边界*/ }for(i=1;i<=79;i++){gotoxy(1+i,2); /*在第2行,第2列开始*/cprintf("%c",196); /*在窗口顶端,输出-*/gotoxy(1+i,25); /*在第25行,第2列开始*/cprintf("%c",196); /*在窗口底端,输出-*/}gotoxy(1,1); cprintf("%c",196); /*在窗口左上角,输出-*/gotoxy(1,24); cprintf("%c",196); /*在窗口左下角,输出-*/gotoxy(80,1); cprintf("%c",196); /*在窗口右上角,输出-*/gotoxy(80,24); cprintf("%c",196); /*在窗口右下角,输出-*/gotoxy(7,1); cprintf("%c %c File %c %c",179,17,16,179); /* | < > |*/gotoxy(27,1); cprintf("%c %c Edit %c %c",179,17,16,179); /* | < > |*/gotoxy(47,1); cprintf("%c %c Help %c %c",179,17,16,179); /* | < > |*/gotoxy(5,25); /*跳至窗口底端*/textcolor(1);cprintf(" Row:1 Col:1");gotoxy(68,25);cprintf("V ersion 2.0");}void qview(Hnode *q) /*快速预览文本:开头:#,回车:* */{void view(Hnode *q); /*view()函数声明*/node *p;int i;window(1,1,80,25); /*定义文本窗口大小*/clrscr(); /*清屏*//*循环读取两个单链表中的值:q是一个指向行单链表首节点的指针,此单链表数据域的值为实际保存各行字符的列单链表p中的首节点地址*/do{p=q->next; /*p指向保存行数据的列单链表的首节点的地址*/cprintf("#"); /*每行开头,打印此字符,不管前面是否有回车符*/while(p!=NULL) /*循环读取单链表p中的值*/{if(p->ch==13) putch('*'); /*若为回车键,打印出*号*/elseputch(p->ch); /*输出各行中的字符到预览窗口*/p=p->next; /*指向下一个节点*/}q=q->nextl; /*指向下一个节点*/printf("\n");/*输出一个回车*/}while(q!=NULL);getch();clrscr();drawmain();/*按任意键后,回到主窗口界面*/window(2,2,79,23);textbackground(9);for(i=0;i<24;i++)insline(); /*插入24个空行*/window(3,3,78,23);textcolor(10);}void view(Hnode *q) /*按行显示保存在单链表中的文本字符,q为指向行单链表中第一个节点的指针*/{node *p; /*p为保存列单链表节点元素地址的指针*/clrscr(); /*清屏*//*双重循环,读取并显示保存在单链表中字符*/do{p=q->next;while(p!=NULL&&p->ch>=32&&p->ch<127&&p->ch!=13&&p->ch!=-1) /*指针p不能为空,且数据域必须为常规字符*/{putch(p->ch);/*在文本窗口中输出该字符*/p=p->next; /*指向下一个节点*/}q=q->nextl; /*指向下一个节点*/if((p->ch==13||p->ch==-1)&&q!=NULL) gotoxy(1,wherey()+1); /*若ch为回车或EOF标记,光标跳至下行的开始处*/}while(q!=NULL); /*逐行逐列显示文本字符*/}int check(Hnode *Hhead,int m,int n) /*check():在单链表中检查第m行第n列位置的字符,若为常规字符,则返回该字符*/{int i;Hnode *q;node *p;q=Hhead;for(i=1;i<m;i++) /*定位至行单链表中的第m个元素*/q=q->nextl;p=q->next;/*获取第m个节点的数据域*/for(i=1;i<n;i++) /*定位至列单链表中的第n个元素*/p=p->next;if(p->ch==13) return -1; /*若第m行,第n列的字符为回车键,则返回-1*/if(p->ch>=32&&p->ch<127) return p->ch; /*若第m行,第n列的字符为常规字符,则返回该字符*/else return 0; /*若第m行,第n列的字符既非回车符又非常规字符,则返回0*/}int judge(Hnode *Hhead,int m) /*judge():返回第m行中的常规字符总的个数,不包括回车符*/ {Hnode *q;node *p;int i,num=0;q=Hhead;for(i=1;i<m;i++) /*定位至行单链表中的第m个元素*/q=q->nextl;if(q==NULL) return -1; /*返回-1,表示第m行不存在*/p=q->next;while(p->next!=NULL){p=p->next;num++; /*统计第m行的字符个数*/}/*行尾字符还没有判断,接下来判断行尾字符*/if(p->ch==13&&num==0) return 0; /*返回0,表示当前行只有一个回车字符*/if(p->ch>=32&&p->ch<127) return num+1; /*返回num+1,表示当前行的最后一个字符为常规字符*/if(p->ch==13&&num!=0) return num; /*返回num,表示当前行的最后一个字符为回车符,不计算在内*/else return 1;/*返回num,表示当前行中只有一个字符,且没有回车符*/}int del(Hnode *Hhead,int m,int n) /*del():删除第m行,第n列位置的字符*/{Hnode *q,*q1;node *p1,*p2,*tail;int i,num=0,j,flag=0;q=Hhead;if(n==0&&m==1) return; /*第1行,第0列不存在*/if(n==0&&m>1) /*若为第0列字符,但行必须大于1,执行向上行移处理*/{n=76;m=m-1;gotoxy(n,m);/*移至第m-1行,第76列*/flag=1; /*移位的标志置1*/}for(i=1;i<m;i++) /*定位至行单链表中的第m个元素*/q=q->nextl;p1=q->next;for(i=1;i<n-1;i++) /*定位至列单链表中的第n-1个元素*/p1=p1->next;p2=p1->next; /*p2指向列单链表中的第n个元素*/if(n==1) /*若是删除第m行第1列的字符*/{q->next=p1->next;free(p1);}else{p1->next=p2->next; /*在单链表中删除第m行第n列的元素*/free(p2);}/*删除掉第m行第n列的元素后,处理行单链表中第m个节点后的数据向前移的任务*/while((num=judge(Hhead,m++))>0) /*执行一次judge(Head,m)后,m才加1.这里必须满足行常规字符数不为0的条件*/{p1=q->next; q1=q;if(p1!=NULL) /*若当前行非空*/{while(p1->next!=NULL)p1=p1->next;tail=p1;/*tail保存列单链表最后一个元素的地址*/q=q->nextl; /*指向下一行的元素的地址*/p1=p2=q->next;tail->next=p1; /*tail的指针域指向下一行的第一个元素的地址*/}else /*若当前行的字符个数为0,即删除该字符后,只剩下回车符,则将下一个行单链表中节点的数据域移至前一下节点的数据域*/{q=q->nextl; p1=p2=q->next;q1->next=p1;/*q1->next指向下一行的第一个元素的地址*/}for(i=0;i<76-num;i++)/*当前行还有76-num个空位没有字符,在下一行的单链表中读取字符,直至遇到回车符为止*/{p1=p2; /*p1指向p2的前一个节点,p2指向行单链表中下一个节点*/p2=p2->next;if(p2->ch==13) break; /*若为回车,跳出循环*/}q->next=p2; /*在列单链表中去掉移至上行的元素*/p1->next=NULL;/*下行移至上行的最后一个元素,指针置空*/ }return flag; /*返回0:表示没有换位,返回1:表示有换位*/}/*执行insert()后,检验第n行及后面的数据,使其满足规则*/int test(Hnode *Hhead,int n){int i=0,num1=1;node *p1,*p2,*tail,*temp1,*temp2;Hnode *q;q=Hhead;for(i=1;i<n;i++) /*定位至行单链表中的第n个元素*/q=q->nextl;tail=p1=q->next;if(p1==NULL) return; /*若此行没有任何字符,则返回*/while(tail->next!=NULL) /*定位至列单链表中的最后一个元素*/tail=tail->next;/*若此单链表中没有回车符且有超过76个节点时,则p1会指向此列单链表中的第76个节点*/for(i=0;i<75;i++){if(p1->ch==13||p1->next==NULL) break;p1=p1->next;}p2=p1->next;p1->next=NULL; /*在此行的最后一个字符的前一个字符处断行,因为插入在此行插入了一个新的字符*/if(tail->ch!=13) /*若此行行尾不是回车键*/{if(p1->ch==13&&q->nextl==NULL)/*若p1的数据域为回车符且行单链表中只有n个节点*/{q->nextl=(Hnode *)malloc(sizeof(Hnode)); /*新建一个行单链表节点,相当于添加一个新行*/q->nextl->nextl=NULL;tail->next=(node *)malloc(sizeof(node));/*在tail所指节点位置开始继续准备添加字符*/tail->next->ch=13; tail->next->next=NULL;q->nextl->next=p2; /*新行单链表节点保存此行多出的字符*/ }else /*若此行行尾和行中都没有回车键,或者q->nextl不为空*/{q=q->nextl;/*q->nextl有可能为空*/tail->next=q->next;/*将多出的字符与下一行的字符相连*/q->next=p2;/**/if(q!=NULL) test(Hhead,++n); /*若行单链表第n个节点后还有节点,继续test()的相同处理*/}}else /*若此列单链表最后一个元素为回车符*/{temp2=p2; /*p2指向第77个字符,或者为空(为空表示此行插入一个字符后,没有超出范围*/while(q!=NULL&&p2!=NULL) /*q指向行列表中的第n个节点.条件:行单链表中第n个节点存中且有第77个字符*/{ /*条件:在行单链表中只有n个节点,且字符超过了一行规定的76个,且num1标志为1*/if((q->nextl==NULL)&&(p1!=tail||p2!=NULL)&&(num1==1)){num1++;q->nextl=(Hnode *)malloc(sizeof(Hnode)); /*新建一个行单链表节点,准备存储此行中多出的字符*/q->nextl->nextl=NULL; q->nextl->next=NULL; /*初始化值*/}/*行单链表中第n+1个节点已经存在,下面为在行单链表中插入一个新的节点*/q=q->nextl; /*q指向行列表中的第n+1个节点*/temp1=q->next;q->next=temp2; /*q的数据域为此行中多出的字符所在的列单链表中的节点地址*/temp2=temp1;}}}void insert(Hnode *Hhead,int m,int n, char a) /*第m行,第n列的位置之前一个位置,插入单字符*/{int i;Hnode *q;node *p,*p1,*p2;q=Hhead;for(i=1;i<m;i++) /*定位至行单链表中的第m个元素*/q=q->nextl;p1=q->next;for(i=1;i<n-1;i++) /*定位至列单链表中的第n-1个元素*/p1=p1->next;p=(node *)malloc(sizeof(node)); /*创建一个新的列单链表节点*/p->ch=a; /*给此节点的数据域赋值*/if(n==1) /*插入之前,若只有一个字符在行中,则插在此节点之前*/{p->next=q->next;q->next=p;}else{p->next=p1->next; /*在第m行,第n列的字符前,插入一字符*/p1->next=p;}test(Hhead,m); /*在插入新元素后,检验并处理单链表中第m行开始的元素,使其满足规则*/}/*对控制键进行响应,A:按键的整数值,Hhead:行单链表的首地址*/void control(int A, Hnode *Hhead){void colorview(Hnode *,int,int); /*函数声明*/int x,y,flag=0;x=wherex(); y=wherey(); /*得到当前光标的坐标值*/if((A==CL)&&(x!=1)) /*ctrl+←,当前光标不是在行首,光标移动*/gotoxy(wherex()-1,wherey());if((A==CL)&&(x==1)) /*ctrl+←,在行首*/gotoxy(abs(judge(Hhead,wherey()-1)),wherey()-1); /*judge(Hhead,wherey()-1)上一行的字符个数作为x值,光标移动*/if((A==CR)&&check(Hhead,wherey(),wherex())>0) /*ctrl+→,当前光标的右边有字符,光标移动*/{ flag=1; gotoxy(wherex()+1,wherey()); }if((A==CR)&&check(Hhead,wherey()+1,1)>0&&check(Hhead,y,x)==0) /*ctrl+→,当前光标处没有字符但下一行的第一列有字符,光标移动*/{ flag=1; gotoxy(1,wherey()+1); }if((A==CR)&&x==76) /*ctrl+→,当前光标在当前行的行尾,光标移动*/{ flag=1; gotoxy(1,wherey()+1); }if(A==CR&&flag==1) /*ctrl+→,光标已经跳至新处,将当前光标所在位置的字符的坐标和值保存在r数组中*/{r[abs(value)].col=wherex();r[abs(value)].line=wherey();r[abs(value)].ch=check(Hhead,r[abs(value)].line,r[abs(value)].col);if(r[abs(value)].ch==-1) r[abs(value)].ch=13; /*若第line行,第col列的字符为回车键,则返回-1*/value--;}if(A==CL&&(x!=1||y!=1)) /*ctrl+←,当前光标并不在窗口左上角,将当前光标所在位置的字符的坐标和值保存在r数组中*/{r[abs(value)].col=wherex();r[abs(value)].line=wherey();r[abs(value)].ch=check(Hhead,r[abs(value)].line,r[abs(value)].col);value++;}colorview(Hhead,wherex(),wherey());}/*用不同的前背景色显示选择的字符*/void colorview(Hnode *Hhead,int x,int y){int i;view(Hhead);/*重新显示所有文本字符*/for(i=0;i<abs(value);i++) /*value为数组下标*/{gotoxy(r[i].col,r[i].line);textbackground(7);textcolor(0);if(r[i].ch!=13&&r[i].ch!=-1)cprintf("%c",r[i].ch);if(r[i].ch==13||r[i].ch==-1)cprintf(" ");}gotoxy(x,y);}void drawmenu(int m,int n) /*画菜单,m:第几项菜单,n:第m项的第n个子菜单*/{int i;if(m%3==0) /*画File菜单项*/{window(8,2,19,9);textcolor(0);textbackground(7);for(i=0;i<7;i++) /*在上面定义的文本窗口中先输出7个空行*/{gotoxy(1,1+i);insline();}window(1,1,80,25);gotoxy(7,1);for(i=1;i<=7;i++){gotoxy(8,1+i);cprintf("%c",179); /*窗口内文本的输出函数,在窗口左边输出| */gotoxy(19,1+i);cprintf("%c",179); /*窗口内文本的输出函数,在窗口右边输出| */ }for(i=1;i<=11;i++){gotoxy(8+i,2);cprintf("%c",196); /*窗口内文本的输出函数,在窗口上边输出- */gotoxy(8+i,9);cprintf("%c",196); /*窗口内文本的输出函数,在窗口下边输出- */ }textbackground(0);gotoxy(10,10); cprintf(" "); /*输出下边的阴影效果*/for(i=0;i<9;i++){gotoxy(20,2+i);cprintf(" "); /*输出右边的阴影效果*/}/*以上为显示菜单项的外观*/textbackground(7);gotoxy(8,2); cprintf("%c",218); /*输出四个边角表格符*/gotoxy(8,9); cprintf("%c",192);gotoxy(19,2); cprintf("%c",191);gotoxy(19,9); cprintf("%c",217);gotoxy(9,3); cprintf(" New ");gotoxy(9,4); cprintf(" Open ");gotoxy(9,5); cprintf(" Save ");gotoxy(9,6); cprintf(" Save as");for(i=1;i<=10;i++){gotoxy(8+i,7);cprintf("%c",196); /*在Save as下输出一行分隔符*/ }gotoxy(9,8); cprintf(" Exit");textcolor(15); textbackground(0);gotoxy(7,1);cprintf("%c %c File %c %c",179,17,16,179);switch(n%5){case 0:gotoxy(9,3); cprintf(" New "); break;case 1:gotoxy(9,4); cprintf(" Open "); break;case 2:gotoxy(9,5); cprintf(" Save "); break;case 3:gotoxy(9,6); cprintf(" Save as "); break;case 4:gotoxy(9,8); cprintf(" Exit "); break;}}/********************************************************/ if(m%3==1) /*画Edit菜单项*/{window(28,2,38,7);textcolor(0);textbackground(7);for(i=0;i<5;i++){gotoxy(1,1+i);insline();}window(1,1,80,25);gotoxy(27,1);for(i=1;i<=5;i++){gotoxy(28,1+i);cprintf("%c",179);gotoxy(39,1+i);cprintf("%c",179);}for(i=1;i<=11;i++){gotoxy(28+i,2);cprintf("%c",196);gotoxy(28+i,7);cprintf("%c",196);}textbackground(0);gotoxy(30,8); cprintf(" ");for(i=0;i<7;i++){gotoxy(40,2+i);cprintf(" ");}textbackground(7);gotoxy(28,2); cprintf("%c",218);gotoxy(28,7); cprintf("%c",192);gotoxy(39,2); cprintf("%c",191);gotoxy(39,7); cprintf("%c",217);gotoxy(29,3); cprintf("Cut ");gotoxy(29,4); cprintf("Copy ");gotoxy(29,5); cprintf("Paste ");gotoxy(29,6); cprintf("Clear ");textcolor(15); textbackground(0);gotoxy(27,1);cprintf("%c %c Edit %c %c",179,17,16,179);switch(n%4){case 0:gotoxy(29,3); cprintf(" Cut "); break;case 1:gotoxy(29,4); cprintf(" Copy "); break;case 2:gotoxy(29,5); cprintf(" Paste "); break;case 3:gotoxy(29,6); cprintf(" Clear "); break;}}/*********************************************************/ if(m%3==2) /*画Help菜单项3*/{window(48,2,48,6);textcolor(0);textbackground(7);for(i=0;i<3;i++){gotoxy(1,1+i);insline();}window(1,1,80,25);gotoxy(47,1);for(i=1;i<=5;i++){gotoxy(48,1+i);cprintf("%c",179);gotoxy(59,1+i);cprintf("%c",179);}for(i=1;i<=11;i++){gotoxy(48+i,2);cprintf("%c",196);gotoxy(48+i,6);cprintf("%c",196);}textbackground(0);gotoxy(50,7); cprintf(" ");for(i=0;i<6;i++){gotoxy(60,2+i);cprintf(" ");}textbackground(7);gotoxy(48,2); cprintf("%c",218);gotoxy(48,6); cprintf("%c",192);gotoxy(59,2); cprintf("%c",191);gotoxy(59,6); cprintf("%c",217);gotoxy(49,3); cprintf("Help... ");gotoxy(49,5); cprintf("About... ");for(i=1;i<=10;i++){gotoxy(48+i,4);cprintf("%c",196);}textcolor(15); textbackground(0);gotoxy(47,1);cprintf("%c %c Help %c %c",179,17,16,179);switch(n%2){case 0:gotoxy(49,3); cprintf("Help... "); break;case 1:gotoxy(49,5); cprintf("About... "); break; }}}int menuctrl(Hnode *Hhead,int A) /*菜单控制*/{int x,y,i,B,value,flag=100,a,b;x=wherex(); y=wherey();if(A==F1) { drawmenu(0,flag); value=300; } /*显示File及其子菜单,并将光带显示在第一个子菜单上*/if(A==F2) { drawmenu(1,flag); value=301; } /*显示Edit及其子菜单,并将光带显示在第一个子菜单上*/if(A==F3) { drawmenu(2,flag); value=302; } /*显示Help及其子菜单,并将光带显示在第一个子菜单上*/if(A==F1||A==F2||A==F3){while((B=bioskey(0))!=ESC) /*选择用户按键*/{if(flag==0) flag=100;if(value==0) value=300; /*此value为局部变量*/if(B==UP) drawmenu(value,--flag); /*循环上下移*/if(B==DOWN) drawmenu(value,++flag); /*循环上下移*/if(B==LEFT) /*菜单项之间循环选择(左移)*/{flag=100;drawmain();window(2,2,79,23);textbackground(9);for(i=0;i<24;i++)insline();window(3,3,78,23);textcolor(10);view(Hhead);drawmenu(--value,flag);}if(B==RIGHT)/*菜单项之间循环选择(右移)*/{flag=100;drawmain();window(2,2,79,23);textbackground(9);for(i=0;i<24;i++)insline();window(3,3,78,23);textcolor(10);view(Hhead);drawmenu(++value,flag);}if(B==ENTER) /*选中某主菜单项的子菜单项(选中某项)*/{if(value%3==0) b=5; /*File下有5个子菜单项*/if(value%3==1) b=4; /*Edit下有4个子菜单项*/if(value%3==2) b=2; /*Help下有2个子菜单项*/a=(value%3)*10+flag%b;/*a表示选择子菜单的编号*/drawmain();window(2,2,79,23);textbackground(9);for(i=0;i<24;i++)insline();window(3,3,78,23);textcolor(10);view(Hhead);gotoxy(x,y);if(a==0) return 100; /*New*/if(a==1) return 101; /*Open*/if(a==2) return 102; /*Save*/if(a==3) return 103; /*Save As*/if(a==4) exit(0); /*Exit*/if(a==10) return Cx; /*Cut*/if(a==11) return Cc; /*Copy*/if(a==12) return Cv; /*Paste*/if(a==13) return DEL;/*Clear*/if(a==20) return 120; /*Help... */if(a==21) return 121; /*About...*/}gotoxy(x+2,y+2);}/*若按键非F1、F2、F3*/drawmain();window(2,2,79,23);textbackground(9);for(i=0;i<24;i++)insline();window(3,3,78,23);textcolor(10);view(Hhead);gotoxy(x,y);}return A;}/*将head所指的行单链表中所指的各个列单链表中的数据域的值写入文件,文件路径和文件名由用户指定*/void save(Hnode *head){FILE* fp;Hnode *q;node *p;int count=0,x,y;char filename[10]; /*保存文件名*/q=head;clrscr();/*清屏*/printf("Enter infile name,for example [c:\\wb.txt]:");/*输入文件名格式*/scanf("%s",filename); /*输入文件名*/fp=fopen(filename,"w");if(fp==NULL) /*打开文件失败*/{printf("\n=====>open file error!\n");getchar();return ;}do{p=q->next; /*指向node类型的数据*/while(p!=NULL){ if((int)p->ch==13){fputc('\n',fp);p=p->next; count++;}else{fputc(p->ch, fp);p=p->next;count++;}}q=q->nextl;}while(q!=NULL);fclose(fp); /*关闭此文件*/return ;}/*文件另存为:将head所指的行单链表中所指的各个列单链表中的数据域的值写入文件,文件路径和文件名由用户指定*/void saveas(Hnode *head){FILE* fp;Hnode *q;node *p;int count=0,x,y;char filename[10]; /*保存文件名*/q=head;clrscr();/*清屏*/printf("Enter infile name,for example [c:\\wb.txt]:");/*输入文件名格式*/scanf("%s",filename); /*输入文件名*/fp=fopen(filename,"w");if(fp==NULL) /*打开文件失败*/{printf("\n=====>open file error!\n");getchar();return ;}do{p=q->next; /*指向node类型的数据*/while(p!=NULL){ if((int)p->ch==13){fputc('\n',fp);p=p->next; count++;}else{fputc(p->ch, fp);p=p->next;count++;}}q=q->nextl;}while(q!=NULL);fclose(fp); /*关闭此文件*/return ;}/*从任意文本文件中读取文件内容,保存至行单链表和列单链表形式的数据结构中*/void opens(Hnode *Hp){FILE* fp;Hnode *q11,*q22;node *p11,*p22,*hp;char temp;int count=0,flags=1;char filename[10]; /*保存文件名*/clrscr();/*清屏*/printf("Enter infile name,for example [c:\\wb.txt]:");/*输入文件名格式*/scanf("%s",filename); /*输入文件名*/fp=fopen(filename,"r");/*以只读方式打开文件,filename必须要存在*/if(fp==NULL)/*打开文件失败*/{ textbackground(2);textcolor(13);cprintf("open file error!");getchar();exit(0) ;}q11=Hp;while(!feof(fp)){ count=0;flags=1;q22=(Hnode *)malloc(sizeof(Hnode));/*新建一个行单链表中的节点*/p11=(node *)malloc(sizeof(node)); /*新建一个列单链表中的节点*/while((temp=fgetc(fp))!=10&&count<=76&&!feof(fp)) /*循环结束,表示在单链表中一行处理完毕,开始新行*/{ p22=(node *)malloc(sizeof(node));/*新建一个列单链表中的节点*/if(flags==1) {hp=p22;flags=0;} /*hp保存列单链表中的首节点的地址*/p22->ch=temp; p22->next=NULL;p11->next=p22; p11=p22;count++;}if(temp==10){ /*若为换行符,将其转换为回车符,因为在程序中,是按回车符处理的*/ p22=(node *)malloc(sizeof(node));p22->ch=13; p22->next=NULL;p11->next=p22; p11=p22;}if(!feof(fp))/*若没此条件,文件最后一行会处理两次.*/{q22->next=hp;q22->nextl=NULL; /*将存储了字符的新列单链表与行单链表中的新节点建立关联*/q11->nextl=q22;q11=q22;}}fclose(fp);Hp=Hp->nextl;/*因为Hp的所在节点的数据域为空,所以Hp=Hp->nextl*/return ;}void main(){char a;int i,A,x,y,flag=0,b;Hnode *Hhead,*q;node *p1,*p2;Hhead=(Hnode *)malloc(sizeof(Hnode)); /*为行单链表中首节点分配内存空间*/q=Hhead; Hhead->nextl=NULL;p1=p2=q->next=(node *)malloc(sizeof(node)); /*为列单链表中首节点分配内存空间*/p1->ch=13; p1->next=NULL;drawmain(); /*显示主窗口*/window(2,2,79,23);textbackground(9);for(i=0;i<24;i++)insline();window(3,3,78,23);textcolor(10);while(1){while(bioskey(1)==0) continue; /*等待用户按键*/a=A=bioskey(0); /*返回输入的字符的键值*/if(a>=32&&a<127) /*若输入为常规字符或回车键*/{if(check(Hhead,wherey(),wherex())<=0)/*当前位置没有字符且输入是常规字符,则执行添加字符操作*/{NUM++;p2->ch=a;putch(a);if(NUM==76) /*连续输入满行,分别生成一个新的行单链表和列单链表节点*/{p2->next=NULL;q->nextl=(Hnode *)malloc(sizeof(Hnode));q=q->nextl; q->nextl=NULL; q->next=NULL;p1=p2=q->next=(node *)malloc(sizeof(node));p1->ch=13; p1->next=NULL;NUM=0;}else /*连续输入未满一行,生成一个新的列单链表节点*/{p2->next=(node *)malloc(sizeof(node));p2=p2->next;p2->ch=13;p2->next=NULL;}}else /*当前位置有字符且输入是常规字符,则执行插入字符操作*/{x=wherex(); y=wherey();insert(Hhead,wherey(),wherex(),a);NUM++;view(Hhead);gotoxy(x,y);}}/*若输入为回车键*/if(a==13){gotoxy(1,wherey()+1);q->nextl=(Hnode *)malloc(sizeof(Hnode));q=q->nextl; q->nextl=NULL; q->next=NULL;p1=p2=q->next=(node *)malloc(sizeof(node));p1->ch=13; p1->next=NULL;NUM=0;}x=wherex(); y=wherey();/*文本窗口中左移,当前光标不在窗口的第1列*/if((A==LEFT)&&(x!=1)) gotoxy(wherex()-1,wherey());/*文本窗口中左移,当前光标在窗口的第1列*/if((A==LEFT)&&(x==1))gotoxy(abs(judge(Hhead,wherey()-1)),wherey()-1);/*文本窗口中右移,若当前光标的右边一位有字符*/if((A==RIGHT)&&check(Hhead,wherey(),wherex())>0)gotoxy(wherex()+1,wherey());/*文本窗口中右移至下行的第1列,若当前光标位置没有字符且下行的第1列有字符*/if((A==RIGHT)&&check(Hhead,wherey()+1,1)!=0&&check(Hhead,y,x)<=0) gotoxy(1,wherey()+1);/*右移*/if((A==RIGHT)&&x==76) gotoxy(1,wherey()+1);/*上移*/if((A==UP)&&check(Hhead,wherey()-1,wherex())!=0)gotoxy(wherex(),wherey()-1);/*上移*/if((A==UP)&&check(Hhead,wherey()-1,wherex())<=0){if(judge(Hhead,wherey()-1)==0)gotoxy(-judge(Hhead,wherey()-1)+1,wherey()-1);elsegotoxy(-judge(Hhead,wherey()-1),wherey()-1);}/*下移*/if((A==DOWN)&&check(Hhead,wherey()+1,wherex())!=0)gotoxy(wherex(),wherey()+1);/*处理BackSpace键*/if(A==BACK) /*处理BackSpace键*/{flag=del(Hhead,wherey(),wherex()-1);x=wherex()-1; y=wherey();view(Hhead);if(flag==0){if(x!=0) gotoxy(x,y);else gotoxy(x+1,y);}if(flag==1){gotoxy(x+1,y);flag=0;}}/*处理菜单按键F1 F2 F3*/if((A==F1)||(A==F2)||(A==F3)||(a<32||a>127)){ A=menuctrl(Hhead,A);if(A==100){main();} /*新建文件*/if(A==101){ /*打开文件*/Hhead=(Hnode *)malloc(sizeof(Hnode));opens(Hhead);getchar();clrscr();gotoxy(3,3);view(Hhead);}/*保存文件*/if(A==102){save(Hhead);clrscr();cprintf("savesuccessfully!");getch();gotoxy(3,3);view(Hhead);}/*文件另存为*/if(A==103){saveas(Hhead);clrscr();cprintf("save as successfully!");getch();gotoxy(3,3);view(Hhead);}/*帮助*/if(A==120){clrscr();cprintf("<Help> F1:File F2:Edit F3:Help ");getch();gotoxy(3,3);view(Hhead);}if(A==121){clrscr();cprintf("Abort:V ersion 2.0 Tel:XXXXXXXXXX");getch();gotoxy(3,3);view(Hhead);}}/*处理DEL键,删除当前位置的单个字符*/if(A==DEL){x=wherex(); y=wherey();del(Hhead,wherey(),wherex());view(Hhead);gotoxy(x,y);}/*处理已经选定文本字符后,按DEL键的情况*/if(A==DEL&&value!=0){if(value>0)x=wherex(), y=wherey();elsex=r[0].col, y=r[0].line;for(i=0;i<abs(value);i++){if(value>0)del(Hhead,r[i].line,r[i].col);if(value<0)del(Hhead,r[abs(value)-1-i].line,r[abs(value)-1-i].col);}value=0; /*此value为全局变量*/view(Hhead);gotoxy(x,y);}/*处理Ctrl+x按键*/if(A==Cx&&value!=0){if(value>0)x=wherex(), y=wherey();elsex=r[0].col, y=r[i].line;for(i=0;i<abs(value);i++){if(value>0)del(Hhead,r[i].line,r[i].col);if(value<0)del(Hhead,r[abs(value)-1-i].line,r[abs(value)-1-i].col);}backup=value; /*保存r数组的有值元素的最大下标值*/value=0; /*此value为全局变量*/view(Hhead);gotoxy(x,y);}/*处理Ctrl+c按键*/if(A==Cc&&value!=0){x=wherex(); y=wherey();backup=value; value=0; /*此value为全局变量*/view(Hhead);gotoxy(x,y);}/*处理Ctrl+v按键*/if(A==Cv&&backup!=0){x=wherex(); y=wherey();if(backup<0) /*Ctrl+右移键选定的文本,贴切此当前位置*/for(i=0;i<abs(backup);i++)insert(Hhead,y,x+i,r[i].ch);/*逐个插入*/if(backup>0) /*Ctrl+左移键选定的文本,贴切此当前位置*/for(i=0;i<backup;i++)insert(Hhead,y,x+i,r[backup-1-i].ch);view(Hhead);gotoxy(x,y);}/*快速预览*/if(A==F10){qview(Hhead);view(Hhead);gotoxy(x,y);}/*处理Ctrl+左移键或右移键*/if(A==CL||A==CR) control(A,Hhead);/*显示当前行列号*/x=wherex(); y=wherey();window(1,1,80,25);textcolor(0);textbackground(7);gotoxy(10,25); /*第25行,第10列,输出当前行号wherey()*/cprintf("%-3d",y);gotoxy(24,25); /*第25行,第24列*/cprintf("%-3d",x);window(3,3,78,23);textcolor(10);gotoxy(x,y);textcolor(10);textbackground(1);}}。
数据结构与算法分析课程设计报告项目名称:文本编辑器提交文档学生姓名:王熙提交文档学生学号: 1143111289教师评阅成绩:教师评阅意见:..提交报告时间:年月日1.实验题目:(1)利用List数据结构实现一个文本编辑器。
(2)熟练掌握List数据结构的逻辑结构、存储结构、基本操作。
(3)灵活运用List数据结构的各种基本操作。
(4)熟练掌握如何编辑、编译、链接和运行一个C++程序。
2实验要求:(1)创建一个友好的用户界面:所有操作在控制台实现,由用户输入操作命令,结果显示在控制台窗口;自己定义相应操作的命令字符(一般为单个字符),并给出用户提示。
用户可以输入h(或H)表示要求帮助,此时应显示所有的操作命令及其含义,也可在程序一运行给出显示所有的操作命令及其含义。
(2)能打开/新建一个文本文件,将其内容读入输入缓冲区。
输入缓冲区用List ADT,具体存储结构及实现单链表,双向链表均可)一行做为一个自选,可用顺序表,也可用链表(链表用数组元素(顺序表)或一个结点(链表)。
(3)能对当前文件内容进行编辑,包括:显示当前文件内容,任意行定位并显示、插入一行、一行, 替换当前行、统计文件行数及字符数,查找指定的某个子串、替换某个子串等保存当前文件、重新读入一个文件,退出系统。
3实验环境:软件环境:windows7环境下的VC++6.0;硬件环境:Intel(R) Core(TM) i5-2450M CPU @2.50GHz 4.0GB内存64位操作系统4..算法描述:程序流程图开始提示用户选择操作:打开、新建、定位、插入、删除、替换、统计、保存、退出根据选择进行相应操作否选择退出?是结束类的层次结构,每个类的设计, 包括数据成员和成员函数组成.class Link : public node{private:node* head;node* tail;node* fence;int leftcnt;int rightcnt;public:Link(){init();}~Link() {removeall(); //destructor}void clear(){removeall();init();}bool insert(int num,const string& item);bool deleteoneline(int num);bool append(const string& item);bool remove(string& it);bool changeline(int num,string& str);bool changeonelinecharacter(int num,string& str);bool findinallstring(string& str);bool setStart();bool setEnd();void prev();void next1(){if (fence!=tail) { //don't move fence if right empty fence=fence->next;rightcnt--;leftcnt++;}}int leftlength() const{return leftcnt;} int rightlength() const{return rightcnt;} int longlength() ;bool displayoneline();bool findappointstring(string str);bool setpos(int pos);bool getValue(string& it) const {if(rightlength()==0)return false;it=fence->next->element;return true;}void print() const;void init() ;void removeall() {while(head != NULL){fence = head;head = head->next;delete fence;}}void save_to_file(string filename);void read_from_infile(string filename); };class node{public:string element;node* pre;node* next;public:node(){element = "";pre = NULL;next = NULL;}~node(){}};●测试程序说明(1)、新建一个文件;(2)、输入前三行,分别是aaa , bbb , ccc;(3)、删除第二行;(4)、第二行插入bbb;(5)、第二行替换为kkk;(6)、统计总行数;(7)、将内容保存;5.源程序清单:●添加必要的注释Main.cpp#include "editor.h"int main(){Link item1;char sign='h';string filename1,filename2,str,str2;int num;cout<<"*****************************************************"<<endl<<" 欢迎使用文本编辑器"<<endl<<"*****************************************************"<<endl;cout<<"请输入文件名<eg. file_in.txt>:";cin>>filename1;item1.setStart();item1.setEnd();item1.read_from_infile(filename1);system("CLS");do{switch(sign) {case '?':case 'h':cout<<"*****************************************************************"<<endl;cout <<" 操作步骤"<<endl;cout << " a:只替换某行的某个子字符串 c:改变一行的内容 " << endl<< " d:删除指定的一行 f:根据输入的字符串查找行" <<endl<< " g:显示指定的一行i:插入一行" <<endl<< " r:读取文件k:保存文件"<<endl<< " o:查找子串 q:退出程序"<<endl<< " m:新建文件v:查看所有"<<endl<< " w:当前内容写入另外一个文件x:清屏"<<endl<< " l:总行数"<<endl<<"*****************************************************************"<<endl;break;case'x':system("CLS");break;case'o':cout<<"输入你想查找的子串:";cin>>str;item1.findinallstring(str);break;case'a':cout<<"请问你想修改第几行?: ";cin>>num;cout<<"请输入你要修改的子串";cin>>str;item1.changeonelinecharacter(num,str);break;case'c':cout<<"请问你想修改第几行?:";cin>>num;cout<<"请输入新字符串内容:";cin>>str;item1.changeline(num,str);break;case'd':cout<<"请问你想删掉第几行?:";cin>>num;item1.deleteoneline(num);item1.print();break;case'f':cout<<"请输入你想查找的字符串:"<<endl;cin>>str;item1.findappointstring(str);break;case'g':cout<<"请输入行序号:"<<endl;cin>>num;item1.setpos(num);item1.displayoneline();break;case'i':cout<<"请问你想插在第几行后面:";cin>>num;cout<<"请输入你要插入的字符串:";cin>>str;item1.insert(num,str);item1.print();break;case'l':item1.longlength();break;case'r':{item1.clear();item1.read_from_infile(filename1);item1.print();}break;case'v':item1.print();break;case'w':cout<<"请输入文件名<eg. file_in.txt>:";cin>>filename2;item1.save_to_file(filename2);break;case'k':item1.save_to_file(filename1);break;case'm':char newfile[30];cout<<"请输入新建文件名:"<<endl;cin>>newfile;break;default:cout<<"\n*** 不合法输入 ***\n"<<endl;}cout<<"please input command:";cin>>sign;}while (sign!='q');return 0;}Editor..h#ifndef _EDITOR_H_#define _EDITOR_H_#include <iostream>#include <iomanip>#include <string>using namespace std;#include "node.h"//Double-linked list link node with freelist support class Link : public node{private:node* head;node* tail;node* fence;int leftcnt;int rightcnt;public:Link(){init();}~Link() {removeall(); //destructor}void clear(){removeall();init();}bool insert(int num,const string& item);bool deleteoneline(int num);bool append(const string& item);bool remove(string& it);bool changeline(int num,string& str);bool changeonelinecharacter(int num,string& str);bool findinallstring(string& str);bool setStart();bool setEnd();void prev();void next1(){if (fence!=tail) { //don't move fence if right empty fence=fence->next;rightcnt--;leftcnt++;}}int leftlength() const{return leftcnt;}int rightlength() const{return rightcnt;}int longlength() ;bool displayoneline();bool findappointstring(string str);bool setpos(int pos);bool getV alue(string& it) const {if(rightlength()==0)return false;it=fence->next->element;return true;}void print() const;void init() ;void removeall() {while(head != NULL){fence = head;head = head->next;delete fence;}}//input the data to the inputfile.void save_to_file(string filename);//read the data from the filevoid read_from_infile(string filename);};#endifEditor.cpp#include "editor.h"#include <fstream>using namespace std;/************************************************************************/ /* set start of the link *//************************************************************************/ bool Link::setStart(){fence=head;rightcnt+=leftcnt;leftcnt=0;return true;}/************************************************************************/ /* set end of the link *//************************************************************************/ bool Link::setEnd(){tail = fence;leftcnt+=rightcnt;rightcnt=0;return true;}/************************************************************************//* init the link *//************************************************************************/ void Link::init(){fence=tail=head=new node;leftcnt=rightcnt=0;}/************************************************************************/ /* display the data to the screen. *//************************************************************************/ void Link::read_from_infile(string filename){string elem[100];int count = 0;ifstream infile(filename.c_str(),ios::in);if (!infile) {cout<<"open error!"<<endl;exit(1);}char ch;while ((ch=infile.get()) != EOF) {if(ch != '\n'){elem[count] = elem[count] + ch;}else{append(elem[count]);count++;}}append(elem[count]);cout<<endl;infile.close();}/************************************************************************/ /* input the data to the file. *//************************************************************************/ void Link::save_to_file(string filename){node* temp;temp=head->next;ofstream outfile(filename.c_str(), ios::out);while (temp!=NULL) {outfile<<temp->element<<endl;temp=temp->next;}outfile.close();}/************************************************************************/ /* the insert member function is according the num to *//*find the fence the insert to the next of the fence *//************************************************************************/ bool Link::insert(int num,const string& item){setpos(num);node* temp=new node;temp->element=item;if (fence->next!=NULL) {temp->next=fence->next;fence->next->pre=temp;fence->next=temp;temp->pre=fence;}else {fence->next=temp;temp->pre=fence;tail=fence->next;}rightcnt++;return true;}/************************************************************************/ /* append string to end of the list *//* the list is doubly linked list *//************************************************************************/ bool Link::append(const string&item){node* p;p=tail;tail=tail->next=new node;tail->element = item;tail->pre = p;rightcnt++; //Added to rightreturn true;}/************************************************************************/ /* remove and return first string in right partition *//************************************************************************/ bool Link::remove(string& it){if (fence->next==NULL) { //empty rightreturn false;}it=fence->next->element; //remember valuenode* itemp=fence->next; //remem link nodeif (itemp->next!=NULL) {itemp->next->pre=fence;}elsetail=fence; //reset tailfence->next=itemp->next; //remove from the listdelete itemp; //reclaim spacerightcnt--; //remove from rightreturn true;}/************************************************************************/ /* move fence one stepleft ,no change if left is empty *//************************************************************************/ void Link::prev(){if (fence!=head) { //cannot back up from list headfence=fence->pre;leftcnt--;rightcnt++;}}/************************************************************************/ /* according you enter the number to find the fence *//************************************************************************/ bool Link::setpos(int pos){fence=head;if (pos<0) {fence = head;}else if (pos>rightcnt+leftcnt) {for(int j=0; j<rightcnt+leftcnt; j++)fence = fence->next;}else{for (int i=0;i<pos;i++) {fence=fence->next;}}return true;}/************************************************************************/ /* print the all the node in the list *//************************************************************************/ void Link::print() const{node* temp;int num=0;temp=head;while (temp!=tail->next) {if (num>0) {cout<<num<<" . ";}cout<< temp->element <<" "<<endl;temp=temp->next;num++;}cout<<endl;}/************************************************************************/ /* to calculate the file include the number of the row *//* to calculate the number of the character *//************************************************************************/ int Link::longlength(){string actfor;node* temp;int length=-1,num=0;temp=head;while (temp!=NULL) {actfor=temp->element;num=num+actfor.length();length++;temp=temp->next;}cout<<"the file length is"<<length<<endl;cout<<"the number of the character is:"<<num<<endl;return length;}/************************************************************************/ /* display one line *//************************************************************************/ bool Link::displayoneline(){if (fence!=NULL && fence!=head) {cout<<fence->element<<endl;}else{cout<<"the present line is empty."<<endl;}return true;}/************************************************************************/ /* according your enter string to find the line number *//* print the find number *//************************************************************************/ bool Link::findappointstring(string str){node* temp;int num=0;bool bo=true;temp=head->next;while (temp!=NULL) {num++;if (temp->element==str) {cout<<"找到了!"<<endl;cout<<"字符串在第"<<num<<" 行"<<endl;cout<<"the appointed is :"<<temp->element<<endl;bo=false;}temp=temp->next;}if (bo) {cout<<"抱歉!未找到!"<<endl;}return true;}/************************************************************************/ /* delete one line according you enter the line number *//************************************************************************/ bool Link::deleteoneline(int num)num=num-1;setpos(num);node* q;// if (fence->next==NULL) {// fence->next=NULL;// delete fence->next;// }if (fence==tail) {q=tail;tail=fence->pre;delete q;}else{node* p;p = fence->next;fence->next=fence->next->next;fence->next->pre=fence;delete p;}return true;}/************************************************************************/ /* according you enter line number to find the line *//*replace the find line to you enter string *//************************************************************************/ bool Link::changeline(int num,string& str){setpos(num);fence->element=str;return true;}/************************************************************************/ /* change appointed line's character *//************************************************************************/ bool Link::changeonelinecharacter(int num,string& str){char m[256];char n[256];char z[256];int len=0;string str2;node* temp;setpos(num);temp=fence;strcpy(m,str.c_str());strcpy(n,temp->element.c_str());num=temp->element.find(m,0);if (temp->element.find(m,0) != string::npos) {cout<<"请输入修改后的字符串(必须与上面查的字符串长度相等):";cin>>str2;while (str.length() != str2.length()) {cout<<"错误!长度不一致!"<<endl;cout<<"请再次输入:"<<endl;cout<<"请输入修改后的字符串(必须与上面查的字符串长度相等):";cin>>str2;}len=str2.length();strcpy(z,str2.c_str());for (int j=0;j<len;j++) {n[num]=z[j];temp->element=n;num++;}cout<<"修改成功!"<<endl;}elsecout<<"未找到相应子串."<<endl;return true;}/************************************************************************/ /* find the postation in the file and print it out *//************************************************************************/ bool Link::findinallstring(string& str){char m[256];char n[256];int num=0;node* temp;temp=head;strcpy(m,str.c_str());while (temp->next!=NULL) {temp=temp->next;num++;if (temp->element.find(m,0) != string::npos) {cout<<"在第"<<num<<" 行"<<endl;}elsecout<<"不在第"<<num<<" 行"<<endl;}return true;}void creatfile(){char newfile[30];cout<<"请输入新建文件名:"<<endl;cin>>newfile;fopen(newfile,"w+");}Node.h#ifndef _NODE_H_#define _NODE_H_class node{public:string element;node* pre;node* next;public:node(){element = "";pre = NULL;next = NULL;}~node(){}};#endif6.运行结果:●测试数据选择aaa bbb ccc kkk●测试结果分析能够完完成对字符串的定位、插入、删除、查找、替换和显示等操作。
四川大学软件学院实验报告课程名称数据结构实验课时8 实验项目文本编辑器实验时间12到14周实验目的了解c++类的封装和KMP算法。
实验环境Windows平台 VC6.0++实验内容(算法、程序、步骤和方法)部分函数创建思想:创建过程如下:a、定义LinkList指针变量*temp: LinkList *temp;b、定义文本输入变量ch,记录文本行数变量j,记录每行字符数变量i;c、申请动态存储空间:head->next=(LinkList *)malloc(sizeof(LinkList));d、首行头指针的前驱指针为空:head->pre=NULL;首行指针:temp=head->next;首行指针的前驱指针也为空:temp->pre=NULL;定义没输入字符时文章长度为0:temp->length=0;初始化为字符串结束标志,防止出现乱码:for(i=0;i<80;i++)temp->data[i]='\0';e、利用循环进行文本输入for(j=0;j<LINK_INIT_SIZE;j++)// 控制一页{ for(i=0;i<80;i++) //控制一行{ ch=getchar(); //接收输入字符temp->data[i]=ch; //给temp指向的行赋值····temp->length++;//行中字符长度加1if(ch=='#'){NUM=j; break; //文章结束时,Num来记录整个文章的行数}}}在字符输入的过程中,如果在单行输入的字符超过了80个字符,则需要以下操作:输入字符数大于80,重新分配空间建立下一行temp->next=(LinkList *)malloc(sizeof(LinkList)) ;给temp的前驱指针赋值:temp->next->pre=temp;temp指向当前行:temp=temp->next;将下一行初始化为字符串结束标志,防止出现乱码:for(i=0;i<80;i++)temp->data[i]='\0';记录整个文章的行数:temp->row=NUM+1;返回指向最后一行指针:return temp;文本输入部分到此结束。
实验流程图:menuchangegetline BmeSearchdelete_ch add_charchar display Endmain程序清单Header file#include<iostream>#include<string>using namespace std;int* get_next(char* T, int* next);//声明get_next函数以获取next数组。
int KMP(char *S, char *T);//声明KMP函数调用next函数来进行查找。
int get_choice();//选择要执行的功能。
void serach(string S);//定义查找函数,用于进行字符串查找。
void add_char(string &S);//定义添加函数,用于进行字符串添加。
void change(string &S);//定义替换函数,将修改指定位置上的字符为新指定的字符。
void delete_char(string &S);//定义删除函数,将用于删除指定位置上的字符。
void display(string &S);//显示函数,用于显示当前的字符串。
C++soure file#include"textedit.h"using namespace std;int* get_next(const char* T, int* next){//根据T字符串将所得到的next数组值存在next指针指向的数组中int i = 0, j = -1;int length = strlen(T);int *temp = next;*next = -1;while(i< length){if(j==-1 || *(T+i)==*(T+j)){//如果字符串中第i个字符与从头起第j个相同,则i,j分别向后移一位i++;j++;if(*(T+i)!=*(T+j))//当遇到第一个不相等的字符时,当前的j值就是next数组第i个元素的值*(next+i)=j;else*(next+i)=*(next+j); //如果相等,则从字符串开始第j个元素的next值与当前位置的值相同}elsej=*(next+j); //如果遇到第i个元素和从头起第j个元素不相同,则从第j个元素的next值的位置开始比较,即回溯}return temp;}int KMP(string S, string T){int S_Length = S.length();int T_Length = T.length();if( S_Length < T_Length) //如果目标串比要查找的串要短,直接返回失败return 0;int i = 0, j = 0;int* next = new int[T_Length];get_next(T.c_str(), next);while(i < S_Length && j < T_Length){if(j == -1 || *(S.c_str()+i) == *(T.c_str()+j)){ //如果对应i,j号元素相同,则依次向后错一位,否则通过next函数,将j指针回溯一定距离。
i++;j++;}elsej=*(next+j);}if(j>=T_Length)//实际上当j==T_Length时,即意味着查找成功,返回开始字符所在的位置,否则返回失败return i-T_Length+1;return 0;}int get_choice() //获取用户输入的选项,以进行相应操作。
{int temp;cout<<"请输入你即将执行的操作:\n1--查找\t2--添加\t3--替换\n4--删除\t5--显示当前字符串\t6--退出\n你的选择:";while(true){cin>>temp;if(temp<7&&temp>0)//只有输入1、2、3、4、5、6时候才会返回输入的选项。
return temp;else{cout<<"你的输入有误,请重新输入\n你的选择:";}}}void serach(string S){int k;string T;cout<<"请输入要查找的串:";cin.sync();//清空缓存区,否则将自动读入输入选项时候按下的回车键。
getline(cin,T);if(k=KMP(S,T))//KMP的返回值不为0即查找成功时候,if条件判断认为是真。
cout<<"所要查找的字符串从第"<<k<<"个字符开始。
"<<endl;elsecout<<"查找失败"<<endl;}void add_char(string &S){int k;string m;cout<<"请输入你想插入的位置:";while(true){cin>>k;if(k>=0&&k<=S.length())//插入的位置不能在字符串外面。
break;elsecout<<"你输入的位置有误。
请重新输入你想插入的位置:";}cout<<"请输入你要插入的字符串:";cin.sync();//同前getline(cin,m);S=S.insert(k,m); //将字符串m插到S的第k个位置上。
}void change(string &S){//调用String类中将第k个字符到第m个字符替换为新字符串的函数。
int k,m;string temp;cout<<"请输入由第几个字符开始替换:";while(true){cin>>k;if(k<S.length()&&k>=0)//起始位置必须小于长度且不能等于{cout<<"替换至第几个字符:";while(true){cin>>m;if(m<=S.length()&&m>k)//结尾位置必须不能大于字符串长度,并且不能小于起始位置。
break;elsecout<<"输入有误,请重新输入结尾:";}break;}elsecout<<"输入有误,请重新输入开头:";}cout<<"请输入要替换成的字符串:";cin.sync();getline(cin,temp);S.replace(k,m,temp); //将目标串替换至指定位置。
}void delete_char(string &S){int k,m;cout<<"请输入从第几个字符开始删:";while(true){cin>>k;if(k<S.length()&&k>=0)//若k==S.length(),则下面无法删除0个。
{cout<<"删除的字符个数为:";while(true){cin>>m;if((k+m)<=S.length()&&m>0)//同前,删除的最后一个字符的位置不能超出字符串的长度。
break;elsecout<<"输入有误,请重新输入个数:";}break;}elsecout<<"输入有误,请重新输入开始位置:";}S=S.erase(k,m);}void display(string &S){cout<<"当前的字符串为:"<<endl;cout<<S.data()<<endl;}void main(){int choice;string S;cout<<"请输入一个字符串:"<<endl;getline(cin,S);while(true){choice = get_choice();switch(choice){case 1:serach(S);break;case 2:add_char(S);break;case 3:change(S);break;case 4:delete_char(S);break;case 5:display(S);break;default: exit(0);}}}实验内容(算法、程序、步骤和方法)数据记录和计算结论(结果)基本达到了实验的要求。