C++:设计一个文本行编辑程序,先从输入文件中读取数据,然后根据行编辑命令处理,将结果写到输出文件中。

news2024/11/20 4:53:21

 3.1题目:

设计一个文本行编辑程序

  1. 对文本文件按行进行编辑:先从输入文件中读取数据,然后根据行编辑命令处理,将结果写到输出文件中。
  2. 行编辑命令包括:

序号

行编辑命令格式

功能

*L  m,n

显示从第m至n行的文本

*I  m

……

^Z

插入文本(……)在第m行后

*D  m,n

删除从第m至n行的文本

*R  m,n

……

^Z

用文本(……)替换第m至n行的文本

*X

保存并退出编辑程序

*Q

放弃并退出程序

3.2需求分析:

文本编辑在日常生活中尤为重要,无论是写论文,做表格等等都离不开文本编辑,而比较热门的编辑器,如:微软Word,Excel等都有着相当完整且多样的功能,而很多功能一般只需要点击图标或者设置就能完成,这也离不开软件背后的相关命令的设置,而规范化,模块化的文本编辑指令又有着方便识别和管理的优点,因此面向文本编辑的程序设计的用途是广泛且重要的。

3.3设计思想和方案设计:

  1. 命令中含有较多插入和删除操作,采用链表存储更方便。
  2. 规范化输入,所有的执行都要取决于其命令类型,因此设置一个string型数组存储所有命令类型,每当输入一个命令类型时遍历数组,然后根据相等时所在位置进行Switch case语句,亦或是判断合法。
  3. 详细化输入,针对不同类型给予不同的输入方式,插入文本应该以换行符为标准进行换行读取。
  4. 保存编辑即为把链表所有内容以turnc形式写入,放弃编辑则直接return 0;

3.4核心代码(全部代码):

#include<iostream>
#include<string>
#include<fstream>
using namespace std;
typedef struct N {
	string s;
	struct N* next;
}Node;
int len = 0;	/*链表长度*/
string file;	/*访问文件路径*/
int main() {
	Node* begin = new Node();		/*文本链表*/
	Node* end = begin;
	ifstream ifs;
	while (true) {
		file = "testpage.dat";
		ifs.open(file, ios::in);
		if (file == "null")return 0;
		else {
			string buf;			//读入原有内容到链表
			while (getline(ifs, buf))
			{
				Node* n = new Node();
				n->next = NULL;
				n->s = buf;
				end->next = n;
				end = n;
				len++;
			}
			ifs.close();
			break;
		}
	}
	string command[] = { "*L","*I","*D","*R","*X","*Q" };		/*指令种类*/
	int comlen = 6;
	while (true) {
		string com;
		int c;
		cout << "共有"<<len<<"行文本" << endl << "输入指令" << endl;
		cin >> com;
		bool p = true;
		for (int i = 0; i < 6; i++) {
			if (command[i] == com) {		/*返回位置+1*/
				c = i+1;
				p = false;
				break;
			}
		}
		if (p) {
			cout << "无效指令!" << endl; continue;
		}
		int m, n;
		switch (c) {
		case 1: {
			while (true) {
				cin >> m >> n;
				if (m <= len && m >= 0 && n <= len && n >= 0 && m < n)break;
				else cout << "m,n中存在的不合法数据,请重新输入!" << endl;
			}
			Node* p = begin;
			for (int i = 0; i < m; i++) {		/*直接输出*/
				p = p->next;
			}
			for (int i = m; i <= n; i++) {
				cout << p->s << endl;
				p = p->next;
			}
			break;
		}
		case 2: {
			while (true) {
				cin >> m;
				if (m <= len && m >= 0)break;
				else cout << "m不合法,请重新输入!" << endl;
			}
			int kk = 1;
			if (kk)getchar();	/*吞掉m后的回车*/
			kk--;
			Node* p = begin;
			for (int i = 0; i < m; i++) {
				p = p->next;
			}
			while (true) {
				string txt;
				while (true) {
					char c;
					c = getchar();
					if (c != '\n')txt.push_back(c);		/*不是回车就算在一个字符串里面*/
					else break;
				}
				if (txt == "^Z")break;
				len++;
				Node* q = new Node();		/*插入结点*/
				q->s = txt;
				q->next = p->next;
				p->next = q;
				p = p->next;
			}
			break;
		}
		case 3: {
			cin >> m >> n;
			len -= (n - m + 1);
			Node* p = begin;
			for (int i = 0; i < m-1; i++) {
				p = p->next;
			}
			Node* q = begin;
			for (int i = 0; i < n; i++) {
				q = q->next;
			}
			p->next = q->next;		/*直接连接*/
			break;
		}
		case 4: {
			while (true) {
				cin >> m >> n;
				if (m <= len && m >= 0 && n <= len && n >= 0 && m < n)break;
				else cout << "m,n中存在的不合法数据,请重新输入!" << endl;
			}
			int kk = 1;
			if (kk == 1)getchar();		/*吞n后面的回车*/
			kk--;
			Node* p = begin;
			for (int i = 0; i < m - 1; i++) {
				p = p->next;
			}
			Node* p1 = begin;
			for (int i = 0; i < n; i++) {
				p1 = p1->next;
			}
			len -= (n - m + 1);
			p->next = p1->next;
			while (true) {
				string txt;
				kk--;
				while (true) {
					char c;
					c = getchar();
					if (c != '\n')txt.push_back(c);	/*不是回车就算在一个字符串里面*/
					else break;
				}
				if (txt == "^Z")break;
				len++;
				Node* q = new Node();
				q->s = txt;
				q->next = p->next;
				p->next = q;
				p = p->next;
			}
			break;
		}
		case 5: {
			ofstream ofs;
			ofs.open(file, ios::trunc);		/*保存写入新链表*/
			Node* p = begin->next;
			while (p != NULL) {
				ofs << p->s << endl;
				p = p->next;
			}
			ofs.close();
			return 0;
		}
		case 6: {
			return 0;		/*不保存*/
		}
		}
	}
}

3.5测试用例:

此程序涉及文件操作:

testpage.dat:

运行截图:

3.6总结:

  1. 通过该实验对链表增删操作和文件读写有进一步理解。
  2. 难点还是链表操作,注意增加结点和删除节点时的赋值逻辑要正确。
  3. 自己对链表的操作能力有待更上一步,应该继续努力。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/124610.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

ts概述、ts环境准备和编译、ts类型声明

文章目录1. ts概述2. ts环境准备和编译3. ts类型声明3.1 布尔值3.2 数字类型3.3 字符串类型3.4 any和unknown3.5 void、null、undefined3.6 never类型3.7 字面量类型3.8 枚举类型3.9 object对象类型3.10 数组3.11 元组3.12 自定义类型type3.13 联合类型3.14 交叉类型3.15 类型断…

《深入理解计算机系统》学习笔记 —— 虚拟内存详解

文章目录虚拟内存物理内存、物理地址、虚拟地址虚拟地址空间虚拟内存缓存页表分配页面页命中缺页虚拟内存的好处简化链接mmap虚拟内存的私有性地址翻译我们先看一下使用页表进行地址翻译有哪些东西&#xff1a;虚拟地址到物理地址处理过程页面大小和虚拟地址物理地址关系TLB翻译…

2022年,我45岁,一息尚存不落征帆,静稳前行未来可期

2022年&#xff0c;我45岁&#xff0c;一息尚存不落征帆&#xff0c;静稳前行未来可期&#xff0c; 关键词&#xff1a;模式固定&#xff0c;回顾与审视&#xff0c;不间断地阅读 模式固定 本年的52周&#xff0c;每逢周五我会把还在更新的15册讲书各讲一期。每期讲20分钟左…

nodejs mp2 姿势启动

以前运行 nodejs 代码都是 node xxx.js&#xff1b; 但是很容易就关掉了&#xff0c; 或者你想看跟详细的数据 是看不到的。 可以试试 pm2的方式 运行你的代码&#xff1b;学习新的姿势&#xff01; pm2的安装&#xff1a; 1&#xff1a; npm install pm2 -g C:\Users\Admini…

数据治理:数据治理框架和标准

参考《一本书讲透数据治理》、《数据治理》等 数据治理并不是新概念&#xff0c;在国内外都有实践&#xff0c;这里重点介绍下国内外对数据治理的主流框架和标准 国际数据治理框架 国际上&#xff0c;主流的数据治理框架主要有&#xff1a;ISO数据治理标准、GDI数据治理框架、…

深入浅出scala之函数(匿名函数)(P41-45)

文章目录1.函数的定义2.匿名函数3.递归函数4.无参函数5.方法和函数的区别联系1.函数的定义 package MethodDemoobject FunctionDefinition {// 实现加法的功能&#xff0c;省略写法&#xff0c;把函数体写在返回值的位置val f1 ((a: Int, b: Int) > { a b })val f2 (a: …

Charles - 配置抓Chrome、iOS、Android包环境

官网下载地址&#xff1a;https://www.charlesproxy.com/。 1、设置代理http端口 路径&#xff1a;Proxy > Proxy Settings > Proxies > HTTP proxy > Prot 2、设置代理https端口 路径&#xff1a;SSL Proxying Settings > SSL Proxyin 3、Mac证书配置 …

谷粒商城-基础篇-Day06-属性分组

属性分组 抽取出一个tree组件放到modules下的common下的category.vue <template><el-tree :data"menus" :props"defaultProps" node-key"catId"ref"menu"></el-tree> </template><script> //这里可以…

LVGL学习笔记6 - 输入设备

目录 1. 移植文件 2. 移除多余代码 3. 输入设备初始化 4. 输入设备读回调函数 4.1 LV_INDEV_TYPE_POINTER 4.2 LV_INDEV_TYPE_KEYPAD 4.3 LV_INDEV_TYPE_ENCODER 4.4 LV_INDEV_TYPE_BUTTON 5. 事件 6. 实例 7 Group 7.1 创建Group 7.2 与输入设备关联 7.3 添加对…

低频功率放大器参考电路图解大全

功率放大器一般也被我们称为电压放大器&#xff0c;主要是把微弱信号进行电压放大&#xff0c;其输入输出的电压电流一般很小&#xff0c;不能够直接驱动功率较大的仪器。为了满足使用需求&#xff0c;需要在放大器末级增加功率放大器。而功率放大器主要就是放大信号功率&#…

供应商绩效管理对企业采购组织的重要价值

供应商绩效管理是供应商管理中的重要组成部分&#xff0c;它在企业整个采购管理生命周期中起到重要的作用&#xff0c;作为管理好供应商的一个重要手段&#xff0c;现代企业几乎都会对供应商实施绩效考核。供应商绩效管理是对公司供应商的可靠性、质量和性能的监视和分析。它能…

sec2-GObject

1 类和实例 GObject实例用函数g_object_new创建。GObject不仅仅有实例&#xff0c;也有类。 一个GObject类在第一次访问g_object_new时候创建&#xff0c;只有有一个GObject类存在。GObject实例在任何时候访问g_object_new都会被创建&#xff0c;所以就会创建更多GObject实例…

【剧前爆米花--爪哇岛寻宝】String类型构造,修改的底层逻辑与StringBuilder和StringBuffer的关系

作者&#xff1a;困了电视剧 专栏&#xff1a;《JavaSE语法与底层详解》 文章分布&#xff1a;这是一篇关于String类型及其底层构造的文章&#xff0c;如有疏漏&#xff0c;欢迎大佬指正&#xff01; String对象的创建 字符串的用法比较多&#xff0c;所以String类提供的构造方…

算法复杂度 O(1),O(n),O(logn),O(nlogn)的区别

算法复杂度分为时间复杂度和空间复杂度 时间复杂度是指执行这个算法所需要的计算工作量空间复杂度是指这个算法所需要的内存空间 1.对于一个循环&#xff0c;假设循环体的时间复杂度为O(n),循环次数为n&#xff0c;则这个循环的时间复杂度为O(n*1)。 void aFunc(int n) {for…

嵌入式终端的以太网系统简析

一 初识以太网电路 从硬件的角度看&#xff0c;以太网接口电路主要由 MAC&#xff08;Media Access Control&#xff09;控制器和物理层接口 PHY&#xff08;Physical Layer&#xff09;两大部分构成&#xff0c;一般一个嵌入式终端系统的以太网硬件抽象 如下&#xff1a; 1 网…

数字孪生教学楼3d可视化系统功能介绍

目前&#xff0c;校园教学楼运维管理阶段面临的主要难题有&#xff1a;数据采集不全、数据各自为阵的数据孤岛现象严重&#xff1b;系统的集成度低&#xff0c;缺乏统一、有效的运行维护处理中心平台&#xff1b;能耗巨大&#xff0c;不符合绿色建筑要求&#xff0c;未形成有效…

做了多年的Android开发,自己是否有擅长领域?(Framework 篇)

前言 如今Android 开发行业的招聘需求可谓是越来越高了&#xff0c;如果你想入大厂工作&#xff0c;学历还只是他们的基础入门的门槛&#xff0c;他们不仅要看学历还得看你是否在某块技术领域有着过硬的实力。比如&#xff1a;APP性能优化、Framework底层原理、音视频、APP架构…

数字验证学习笔记——SystemVerilog芯片验证17 ——数组约束

一、数组约束 1.1 数组的属性约束 多数情况下&#xff0c;数组的大小应该给定范围&#xff0c;防止生成过大体积的数组或者空数组此外还可以在约束中结合数组的其他方法sum&#xff08;&#xff09;&#xff0c;product&#xff08;&#xff09;&#xff0c;and&#xff08;&a…

Ansys Zemax | 如何在 OpticStudio 中模拟人眼

本文是人眼模型的一个案例研究&#xff0c;并提供了更高级的序列模式建模技术的演示。我们将在OpticStudio中使用Liou & Brennan 1997眼睛模型创建人眼模型。在OpticStudio中成功生成这个眼睛模型后&#xff0c;我们将使用它来设计一个自由形式的渐进眼镜镜片。 下载 联系…

正大国际期货:2022年各行业顶级富豪身价大洗牌

2022年各行业顶级富豪身价大洗牌 富豪身价较2021年年底变动幅度涨跌幅 行业&#xff1a;加密货币&#xff0c;币安创始人&#xff1a;赵长鹏816%&#xff0c;身价174亿美元 行业&#xff1a;基建、大宗商品&#xff0c;阿达尼集团创始人&#xff1a;高塔姆阿达尼210%&#x…