C语言:文件操作 判断用feof,会重复输出

第一次记录学习经历,希望大佬们带带菜鸡(我)

再记录一下,王者荣耀那个姬小满的一句台词我很喜欢“别羡慕,我可是凭本事摸鱼的”,希望我也能凭本事摸鱼。

这几天在写文件的实验报告,遇到了用feof判断会重复输出的问题

举例:

文件内容:

1 李华 100

2 李白 80

3 李信 70

输出:

1 李华 100

2 李白 80

3 李信 70

3 李信 70

下面是会发生该情况的代码:

#include<stdio.h>
#include<stdlib.h>
int main()
{
	FILE* p = NULL;
	int xh, a[5] = {0},i;
	double cj;
	char xm[20];
	if ((p = fopen("a.txt", "r")) == NULL)
	{
		printf("无法读取文件\n");
		exit(0);
	}
	printf("现为您显示文件内容:\n");
	while (!feof(p))
	{
        fscanf(p, "%d %s %lf",&xh,xm,&cj);
		printf("%d %s %.2lf\n",xh,xm,cj);
		if (cj == 100) a[0]++;
		else if (cj >= 60) a[9 - (int)cj / 10]++;
		else a[4]++;
		
	}
	fclose(p);
	printf("\n");
	printf("等级人数统计如下\n");
	for (i = 0; i < 5; i++)
	{
		printf("等级为%c的人数:%d\n",'A'+i,a[i]);
	}
	return 0;
}

后面才知道,其实是文件最后会有一个eof字符,文件指针不到eof的话,feof就不会判断为空,而我们读的时候,指针会停在读取的最后一个字上面,那当我们读完 李信 70的时候,指针其实是指在0这里的,而不是eof字符,那么再进行第4次判断的时候(也就是读完李信之后的while判断)feof是认为未空的,进入再次fscanf,但是因为文件没得读了,fscanf读失败了,所以变量里面保留了上次读的数据,然后被printf出来,所以有了重复输出。

解决方法有多种:

1.直接拿fscanf的返回值来进行判断,fscanf读取失败就会返回eof

#include<stdio.h>
#include<stdlib.h>
int main()
{
	FILE* p = NULL;
	int xh, a[5] = {0},i;
	double cj;
	char xm[20];
	if ((p = fopen("a.txt", "r")) == NULL)
	{
		printf("无法读取文件\n");
		exit(0);
	}
	printf("现为您显示文件内容:\n");
	while ((fscanf(p, "%d %s %lf",&xh,xm,&cj)) != EOF)
	{
		printf("%d %s %.2lf\n",xh,xm,cj);
		if (cj == 100) a[0]++;
		else if (cj >= 60) a[9 - (int)cj / 10]++;
		else a[4]++;
		
	}
	fclose(p);
	printf("\n");
	printf("等级人数统计如下\n");
	for (i = 0; i < 5; i++)
	{
		printf("等级为%c的人数:%d\n",'A'+i,a[i]);
	}
	return 0;
}

2.在循环外先读一次

#include<stdio.h>
#include<stdlib.h>
int main()
{
	FILE* p = NULL;
	int xh, a[5] = {0},i;
	double cj;
	char xm[20];
	if ((p = fopen("a.txt", "r")) == NULL)
	{
		printf("无法读取文件\n");
		exit(0);
	}
	printf("现为您显示文件内容:\n");
    fscanf(p, "%d %s %lf",&xh,xm,&cj);
	while (!feof(p))
	{
		printf("%d %s %.2lf\n",xh,xm,cj);
		if (cj == 100) a[0]++;
		else if (cj >= 60) a[9 - (int)cj / 10]++;
		else a[4]++;
		fscanf(p, "%d %s %lf",&xh,xm,&cj);
	}
	fclose(p);
	printf("\n");
	printf("等级人数统计如下\n");
	for (i = 0; i < 5; i++)
	{
		printf("等级为%c的人数:%d\n",'A'+i,a[i]);
	}
	return 0;
}

我个人喜欢第一种,简单粗暴一点,当然,搞清楚问题就能正确地应对啦。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值