[I/O]将多个源文件中的内容追加保存一个目标文件末尾

Posted Spring-_-Bear

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了[I/O]将多个源文件中的内容追加保存一个目标文件末尾相关的知识,希望对你有一定的参考价值。

本程序实现把一系列文件中的内容附加在另一个文件的末尾。

程序的设计方案:

  • 询问目标文件的名称并打开它
  • 使用一个循环询问源文件
  • 以只读方式依次打开每个源文件,并将其添加到目标文件的末尾

细化程序打开文件的步骤:

  1. 以附加模式打开目标文件
  2. 如果打开失败,则退出程序
  3. 为该文件创建一个4096字节的缓冲区
  4. 如果创建失败,则退出程序

细化文件拷贝步骤:

  1. 如果该文件与目标文件相同,则跳至下一个文件
  2. 如果以只读模式无法打开文件,则跳至下一个文件
  3. 把文件内容添加至目标文件末尾

最后,程序回到目标文件的开始处,显示当前目标文件的所有内容。

源文件有三个文件:1.txt、2.txt、3.txt ;目标文件名为123.txt
1.txt中的内容共有两行:第一行有十个数字1,第二行包含一个换行符;
2.txt中的内容共有两行:第一行有十个数字2,第二行包含一个换行符;
3.txt中的内容共有一行:内容为十个数字3

  • 运行示例:

在这里插入图片描述

  • 源码:
/* 把一系列源文件中的内容追加保存到一个目标文件 */

#include<stdio.h>
#include<stdlib.h>
#include<string.h>

#define BUFSIZE 4096		// 缓冲区大小
#define SLEN 81				// 数组最大长度

/* 将source文件中的内容追加保存到dest文件中 */
void append(FILE* source, FILE* dest);
/* 创建一个字符串st,串中可有空白 */
char* s_gets(char* st, int n);

int main(void)
{
	FILE* fa, * fs;			// fa指向目标文件,fs指向源文件
	int files = 0;			// 附加的文件数量
	char file_app[SLEN];	// 目标文件名
	char file_src[SLEN];	// 源文件名
	int ch;

	/* 输入目标文件名 */
	puts("Enter name of destination file:");
	s_gets(file_app, SLEN);

	/* 目标文件打开(创建)失败 */
	if ((fa = fopen(file_app, "a+")) == NULL)
	{
		fprintf(stderr, "Can't open %s\\n", file_app);
		exit(EXIT_FAILURE);
	}

	/* 为fa文件创建一个4096字节的缓冲区 */
	if (setvbuf(fa, NULL, _IOFBF, BUFSIZE) != 0)
	{
		fputs("Can't create output buffer\\n", stderr);
		exit(EXIT_FAILURE);
	}

	/* 输入源文件名,键入空结束 */
	puts("Enter name of first source file (empty line to quit):");
	/* 输入源文件名且不为空 */
	while (s_gets(file_src, SLEN) && file_src[0] != '\\0')
	{		
		if (strcmp(file_src, file_app) == 0)					// 源文件不可与目标文件相同
		{
			fputs("Cant't append file to itself\\n", stderr);
		}
		else if ((fs = fopen(file_src, "r")) == NULL)			// 以只读模式打开源文件失败
		{
			fprintf(stderr, "Can't open %s\\n", file_src);
		}
		else
		{
			if (setvbuf(fs, NULL, _IOFBF, BUFSIZE) != 0)		// 创建输入缓冲区
			{
				fputs("Can't create input buffer\\n", stderr);
				continue;
			}

			/* 将文件fs中的内容追加到fa文件末尾 */
			append(fs, fa);										
		
			/* 读源文件时出错 */
			if (ferror(fs) != 0)
			{
				fprintf(stderr, "Error in readiing file %s.\\n", file_src);
			}

			/* 内容写进目标文件时出错 */
			if(ferror(fa) != 0)
			{
				fprintf(stderr, "Error in writing file %s.\\n", file_app);
			}

			/* 关闭源文件 */
			fclose(fs);
			files++;

			/* 当前文件追加保存成功 */
			printf("File %s appended.\\n", file_src);
			puts("Next file (empty line to quit):");
		}
	}

	/* 文件追加保存成功提示 */
	printf("Done appending. %d files appended.\\n\\n", files);

	/* 回到目标文件开头 */
	rewind(fa);

	/* 打印目标文件中的内容 */
	printf("%s contents:\\n", file_app);
	while ((ch = getc(fa)) != EOF)
	{
		putchar(ch);
	}
	puts("\\nDone displaying.");

	/* 关闭目标文件 */
	fclose(fa);

	return 0;
}

/* 将source文件中的内容追加保存到dest文件中 */
void append(FILE* source, FILE* dest)
{
	size_t bytes;

	/* 静态存储期,块作用域 */
	static char temp[BUFSIZE];

	/* 使用fread()和fwrite()一次拷贝4096字节,而不是1字节 */
	while ((bytes = fread(temp, sizeof(char), BUFSIZE, source)) > 0)
	{
		fwrite(temp, sizeof(char), bytes, dest);
	}
}

/* 创建一个字符串st,串中可有空白 */
char* s_gets(char* st, int n)
{
	char* ret_val;
	char* find;

	ret_val = fgets(st, n, stdin);

	if (ret_val)
	{
		/* 在st字符串中查找'\\n' */
		find = strchr(st, '\\n');

		/* 替换掉字符串中的换行符 */
		if (find)
		{
			*find = '\\0';
		}
		else
		{
			while (getchar() != '\\n')
			{
				continue;
			}
		}
	}

	return ret_val;
}

以上是关于[I/O]将多个源文件中的内容追加保存一个目标文件末尾的主要内容,如果未能解决你的问题,请参考以下文章

bash 总结

标准 I/O 和管道

Python文件I/O

如何在 Linux 上使用标准 I/O 函数在多个进程中写入文件?

I/O(输入/输出)

哪些文件占用了我进程的大部分 I/O 时间?