文本编辑

本文介绍了一个基于堆分配存储表示方法的文件操作与编辑系统,包括文件打开、显示、插入、删除、拷贝、修改、查找、替换和存盘功能。系统支持文件名输入,并能对文件内容进行各种编辑操作,但受限于内存容量。为了实现文件大小不受限制,可以考虑使用链表存储文件内容。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

采用的存储结构为:串的堆分配存储表示方法。

/* 文本行编辑 */
//怎样对输入文件内容的大小没有限制?链表???
#include"head.h"

#define MAX_LEN 25				/* 文件最大行数 */
#define LINE_LEN 75				/* 每行字符数最大值+1 */
#define NAME_LEN 20				/* 文件名最大长度(包括盘符、路径)+1 */

/* 全局变量 */
HString T[MAX_LEN];				//相当于存储整个文本
char str[LINE_LEN], filename[NAME_LEN] = "";
FILE *fp;
int n = 0; /* 文件行数 */

void Open()
{ /* 打开文件(新或旧) */
	if (filename[0]) /* 文件已打开 */
		printf("已存在打开的文件\n");
	else
	{
		printf("请输入文件名(可包括盘符、路径,不超过%d个字符): ", NAME_LEN - 1);
		scanf_s("%s", filename, _countof(filename));
		fopen_s(&fp, filename, "r");
		if (fp) /* 已存在此文件 */
		{
			while (fgets(str, LINE_LEN, fp))			//读取一行数
			{
				str[strlen(str) - 1] = 0;				/* 将换行符10强制改为0 */

				if (n > MAX_LEN)
				{
					printf("文件太大\n");
					return;
				}
				
				StrAssign(&T[n], str);					//存到内存数组中
				n++;	
			}
			fclose(fp);									//关闭文件
		}
		else
			printf("新文件\n");
	}
}

void List()
{ /* 显示文件内容 */
	int i;
	for (i = 0; i<n; i++)
	{
		printf("%d: ", i + 1);
		StrPrint(T[i]);
	}
	getchar();
}

void Insert()
{ /* 插入行 */
	int i, l, m;
	printf("在第m行前插n行,请输入l m: ");
	scanf_s("%d%d%*c", &l, &m);
	if (n + m>MAX_LEN)
	{
		printf("插入行太多\n");
		return;
	}
	if (n >= l - 1 && l>0)
	{
		for (i = n - 1; i >= l - 1; i--)
			T[i + m] = T[i];
		n += m;
		printf("请顺序输入待插入内容:\n");
		for (i = l - 1; i<l - 1 + m; i++)
		{
			gets_s(str, _countof(str));
			InitString(&T[i]);
			StrAssign(&T[i], str);
		}
	}
	else
		printf("行超出范围\n");
}

void Delete()
{ /* 删除行 */
	int i, l, m;
	printf("从第l行起删除m行,请输入l m: ");
	scanf_s("%d%d%*c", &l, &m);
	if (n >= l + m - 1 && l>0)
	{
		for (i = l - 1 + m; i<n; i++)
			T[i - m] = T[i];
		for (i = n - m; i<n; i++)
			InitString(&T[i]);
		n -= m;
	}
	else
		printf("行超出范围\n");
}

void Copy()
{ /* 拷贝行 */
	int i, l, m, k;
	printf("把第l行开始的m行插在原k行之前,请输入l m k: ");
	scanf_s("%d%d%d%*c", &l, &m, &k);
	if (n + m>MAX_LEN)
	{
		printf("拷贝行太多\n");
		return;
	}
	if (n >= k - 1 && n >= l - 1 + m && (k >= l + m || k <= l))
	{
		for (i = n - 1; i >= k - 1; i--)
			T[i + m] = T[i];
		n += m;
		if (k <= l)
			l += m;
		for (i = l - 1; i<l - 1 + m; i++)
		{
			InitString(&T[i + k - l]);
			StrCopy(&T[i + k - l], T[i]);
		}
	}
	else
		printf("行超出范围\n");
}

void Modify()
{ /* 修改行 */
	int i;
	printf("请输入待修改的行号: ");
	scanf_s("%d%*c", &i);
	if (i>0 && i <= n) /* 行号合法 */
	{
		printf("%d: ", i);
		StrPrint(T[i - 1]);
		printf("请输入新内容: ");
		gets_s(str, _countof(str));
		StrAssign(&T[i - 1], str);
	}
	else
		printf("行号超出范围\n");
}

void Search()
{ /* 查找字符串 */
	int i, k, f = 1; /* f为继续查找标志 */
	char b;
	HString s;
	printf("请输入待查找的字符串: ");
	scanf_s("%s%*c", str, _countof(str));
	InitString(&s);
	StrAssign(&s, str);
	for (i = 0; i<n&&f; i++) /* 逐行查找 */
	{
		k = 1; /* 由每行第1个字符起查找 */
		while (k)
		{
			k = Index(T[i], s, k); /* 由本行的第k个字符开始查找 */
			if (k) /* 找到 */
			{
				printf("第%d行: ", i + 1);
				StrPrint(T[i]);
				printf("第%d个字符处找到。继续查找吗(Y/N)? ", k);
				b = getchar();
				getchar();
				if (b != 'Y'&&b != 'y') /* 中断查找 */
				{
					f = 0;
					break;
				}
				else
					k++;
			}
		}
	}
	if (f)
		printf("没找到\n");
}

void Replace1()
{ /* 替换字符串 */
	int i, k, f = 1; /* f为继续替换标志 */
	char b;
	HString s, t;
	printf("请输入待替换的字符串: ");
	scanf_s("%s%*c", str, _countof(str));
	InitString(&s);
	StrAssign(&s, str);
	printf("替换为: ");
	scanf_s("%s%*c", str, _countof(str));
	InitString(&t);
	StrAssign(&t, str);
	for (i = 0; i<n&&f; i++) /* 逐行查找、替换 */
	{
		k = 1; /* 由每行第1个字符起查找 */
		while (k)
		{
			k = Index(T[i], s, k); /* 由本行的第k个字符开始查找 */
			if (k) /* 找到 */
			{
				printf("第%d行: ", i + 1);
				StrPrint(T[i]);
				printf("第%d个字符处找到。是否替换(Y/N)? ", k);
				b = getchar();
				getchar();
				if (b == 'Y' || b == 'y')
				{
					StrDelete(&T[i], k, StrLength(s));
					StrInsert(&T[i], k, t);
				}
				printf("继续替换吗(Y/N)?");
				b = getchar();
				getchar();
				if (b != 'Y'&&b != 'y') /* 中断查找、替换 */
				{
					f = 0;
					break;
				}
				else
					k += StrLength(t);
			}
		}
	}
	if (f)
		printf("没找到\n");
}

void Save()
{ /* 存盘 */
	int i;
	getchar();
	fopen_s(&fp, filename, "w");
	if (fp)
	{
		for (i = 0; i<n; i++)
		{
			T[i].ch[T[i].length] = 0;
			fputs(T[i].ch, fp);
			fputc(10, fp);
		}
		fputc(10, fp);
		fclose(fp);
	}
	else
		printf("存盘失败\n");
}

void main()
{
	Status s = TRUE;
	int i, k;
	for (i = 0; i<MAX_LEN; i++) /* 初始化串 */
		InitString(&T[i]);
	while (s)
	{
		printf("请选择: 1.打开文件(新或旧)  2.显示文件内容\n");
		printf("        3.插入行  4.删除行  5.拷贝行  6.修改行\n");
		printf("        7.查找字符串        8.替换字符串\n");
		printf("        9.存盘退出          0.放弃编辑\n");
		scanf_s("%d", &k);
		switch (k)
		{
		case 1: Open();
			break;
		case 2: List();
			break;
		case 3: Insert();
			break;
		case 4: Delete();
			break;
		case 5: Copy();
			break;
		case 6: Modify();
			break;
		case 7: Search();
			break;
		case 8: Replace1();
			break;
		case 9: Save();
		case 0: s = FALSE;
		}
	}

	system("pause");
}


运行结果:

请选择: 1.打开文件(新或旧)  2.显示文件内容
        3.插入行  4.删除行  5.拷贝行  6.修改行
        7.查找字符串        8.替换字符串
        9.存盘退出          0.放弃编辑
1
请输入文件名(可包括盘符、路径,不超过19个字符): file.txt
请选择: 1.打开文件(新或旧)  2.显示文件内容
        3.插入行  4.删除行  5.拷贝行  6.修改行
        7.查找字符串        8.替换字符串
        9.存盘退出          0.放弃编辑
2
1: 11111
2: 22222
3: 33333
4: 44444
5:
请选择: 1.打开文件(新或旧)  2.显示文件内容
        3.插入行  4.删除行  5.拷贝行  6.修改行
        7.查找字符串        8.替换字符串
        9.存盘退出          0.放弃编辑
3
在第m行前插n行,请输入l m: 1 2
请顺序输入待插入内容:
Apple
Lin
请选择: 1.打开文件(新或旧)  2.显示文件内容
        3.插入行  4.删除行  5.拷贝行  6.修改行
        7.查找字符串        8.替换字符串
        9.存盘退出          0.放弃编辑
3
在第m行前插n行,请输入l m: 1 1
请顺序输入待插入内容:
请选择: 1.打开文件(新或旧)  2.显示文件内容
        3.插入行  4.删除行  5.拷贝行  6.修改行
        7.查找字符串        8.替换字符串
        9.存盘退出          0.放弃编辑
2
1:
2: Apple
3: Lin
4: 11111
5: 22222
6: 33333
7: 44444
8:
请选择: 1.打开文件(新或旧)  2.显示文件内容
        3.插入行  4.删除行  5.拷贝行  6.修改行
        7.查找字符串        8.替换字符串
        9.存盘退出          0.放弃编辑
5
把第l行开始的m行插在原k行之前,请输入l m k: 1 2 3
请选择: 1.打开文件(新或旧)  2.显示文件内容
        3.插入行  4.删除行  5.拷贝行  6.修改行
        7.查找字符串        8.替换字符串
        9.存盘退出          0.放弃编辑
2
1:
2: Apple
3:
4: Apple
5: Lin
6: 11111
7: 22222
8: 33333
9: 44444
10:
请选择: 1.打开文件(新或旧)  2.显示文件内容
        3.插入行  4.删除行  5.拷贝行  6.修改行
        7.查找字符串        8.替换字符串
        9.存盘退出          0.放弃编辑
7
请输入待查找的字符串: Lin
第5行: Lin
第1个字符处找到。继续查找吗(Y/N)? Y
没找到
请选择: 1.打开文件(新或旧)  2.显示文件内容
        3.插入行  4.删除行  5.拷贝行  6.修改行
        7.查找字符串        8.替换字符串
        9.存盘退出          0.放弃编辑
0
请按任意键继续. . .



思考:怎么做才能不限制输入文件的大小呢?

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值