第一次记录学习经历,希望大佬们带带菜鸡(我)
再记录一下,王者荣耀那个姬小满的一句台词我很喜欢“别羡慕,我可是凭本事摸鱼的”,希望我也能凭本事摸鱼。
这几天在写文件的实验报告,遇到了用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;
}
我个人喜欢第一种,简单粗暴一点,当然,搞清楚问题就能正确地应对啦。