C语言——文件相关操作补充

一、文件读取结束的判定

当我们使用例如fgetc、fgets、fscanf、fread等函数来读取文件内容时,我们可能遇到需要判断文件读取的结束,一般情况下都是通过这些函数的返回值来判断文件读取是否结束。

1、fgetc

返回读取的字符的ASCII值,如果读到文件末尾或发生错误,则返回EOF(通常定义为-1)。

所以在使用fgetc函数读取文件内容时,要判断文件读取的结束则判断fgetc函数的返回值是否是EOF,如果fgetc函数的返回值为EOF,则可能是达到文件结尾,也就是文件读取结束。

例如使用fgetc以一个个字符读取文件的所有内容并打印出来:

#include <stdio.h>

int main()
{
	FILE* pf = fopen("test.txt", "r");
	if (pf == NULL)
	{
		perror("fopen");
		return -1;
	}

	char ch = 0;
	while ((ch = fgetc(pf)) != EOF)//使用fgetc函数的返回值作为判断,如果是EOF,则可能是读取结束
	{
		printf("%c ", ch);
	}
	printf("\n");

	fclose(pf);
	pf = NULL;
	return 0;
}

文件内容为:

运行结果:

2、fgets

返回指向读取字符串的指针,如果读到文件末尾或发生错误,则返回NULL

如果fgets函数的返回值为NULL,则可能是达到文件结尾,也就是文件读取结束。

例如尝试使用fgets函数将文件的内容一行行读取并打印:

#include <stdio.h>

int main()
{
	FILE* pf = fopen("test.txt", "r");
	if (pf == NULL)
	{
		perror("fopen");
		return -1;
	}

	char str[100] = { 0 };
	while (fgets(str,100,pf) != NULL)//使用fgets函数的返回值作为判断,如果是NULL,则可能是读取结束
	{
		printf("%s", str);
	}

	fclose(pf);
	pf = NULL;
	return 0;
}

文件内容:

运行结果:

3、fscanf

返回成功匹配和赋值的输入项数,如果读到文件末尾或发生错误,则返回EOF

如果fscanf函数的返回值为EOF,则可能是达到文件结尾,也就是文件读取结束。

使用fscanf函数格式化读取文件中所有数据:

#include <stdio.h>

int main()
{
	FILE* pf = fopen("test.txt", "r");
	if (pf == NULL)
	{
		perror("fopen");
		return -1;
	}

	int id = 0;
	char name[10] = { 0 };
	int age = 0;
	while (fscanf(pf, "%d %s %d", &id, name, &age) == 3)//使用fscanf的返回值作为判定条件,如果返回值不等于期望匹配项,则可能是文件读取完成
	{
		printf("%d %s %d\n", id, name, age);
	}

	fclose(pf);
	pf = NULL;
	return 0;
}

文件内容:

运行结果:

4、fread

函数原型:

size_t fread(void *ptr, size_t size, size_t count, FILE *stream);

返回成功读取的元素个数,如果读到文件末尾或发生错误,则返回值可能小于count

文件内容,使用下面的程序写入test.bin文件中:

#include <stdio.h>

int main()
{
	FILE* pf = fopen("test.bin", "wb");
	if (pf == NULL)
	{
		perror("fopen");
		return -1;
	}

	int arr[10] = { 1,2,3,4,5,6,7,8,9,10 };
	fwrite(arr, sizeof(int), sizeof(arr) / sizeof(int), pf);

	fclose(pf);
	pf = NULL;
	return 0;
}

使用二进制编辑器打开查看(这里是小端字节序):

使用fread读取十个整形数据:

#include <stdio.h>

int main()
{
	FILE* pf = fopen("test.bin", "rb");
	if (pf == NULL)
	{
		perror("fopen");
		return -1;
	}

	int temp = 0;
	while (fread(&temp, sizeof(int), 1, pf) == 1)//以fread函数的返回值为判定,因为这里读取元素个数为1,正确读取应当返回1,如果返回值不是1,则可能是文件结尾,也就是文件读取完成
	{
		printf("%d ", temp);
	}
	printf("\n");

	fclose(pf);
	pf = NULL;
	return 0;
}

运行结果:

5、总结

  • 对于fgetc,当返回值为EOF时,可能表示文件读取结束。
  • 对于fgets,当返回值为NULL时,可能表示文件读取结束。
  • 对于fscanf,当返回值为EOF时,可能表示文件读取结束。
  • 对于fread,当返回值小于请求的元素个数count时,可能表示文件读取结束。

二、feof和ferror

在上面的文件读取结束的判定中,只是初步的判定,因为对于那些读取文件的函数的特殊返回值不一定是代表文件到了结尾(文件读取结束),也可能是代表文件读取错误。所以我们需要判断是哪一种情况,到底是文件读取结束还是文件读取错误,就需要下面的两个函数。

1、feof

feof函数用于检测文件的结束标志(End-Of-File)。

函数原型:

函数参数和返回值:

参数 stream 是文件流指针,当文件指针到达文件末尾时,feof函数返回非零值(通常是1),否则返回0。

2、ferror

ferror函数用于检测文件操作是否发生错误。

函数原型:

函数参数和返回值:

参数 stream 是文件流指针,如果在文件操作过程中发生错误,ferror函数返回非零值(通常是1),否则返回0。

3、使用示例:

如果需要区分文件结束和读取错误,可以使用feofferror函数。

test.txt文件内容:

下面的代码尝试以一个个字符读取此文件的全部内容,并且打印出来:

#include <stdio.h>

int main() {
	FILE* pf = fopen("test.txt", "r");
	if (pf == NULL) {
		perror("fopen");
		return 0;
	}

	char ch = 0;
	while ((ch = fgetc(pf)) != EOF) {
		printf("%c ", ch);
	}
	printf("\n");
	if (feof(pf)) {
		printf("文件读取结束\n");
	}
	else if (ferror(pf)) {
		printf("文件读取错误\n");
	}

	fclose(pf);
	pf = NULL;
	return 0;
}

运行结果:

在上述代码中,feof(file)用于检查是否到达文件末尾,而ferror(file)用于检查是否发生了读取错误。这里的结果是文件读取结束。

  • 25
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值