feof()函数陷阱
24 October 2015
先从一个简单的输出开始
一个程序,代码如下:
#include<stdio.h>
int main()
{
char buff[1024];
memset(buff, 0, sizeof(buff));
FILE* f = fopen("a.txt", "r");
while (!feof(f))
{
printf("---not eof\n");
fgets(buff, sizeof(buff), f);
printf("buff is -- %s", buff);
}
printf("----eof!\n");
return 0;
}
文件a.txt的内容是这样的:
abcdef
这个程序的输出结果是:
---not eof
buff is -- abcdef
---not eof
buff is -- abcdef
----eof!
好像哪里不对,为什么会输出两边,进入两次循环,原因是这样的:
feof
函数的功能是检查一个stream在当前其文件结束标志是否被置位,如果已经置位,返回非零值,否则返回零。一个stream的文件结束标志是由当前时间之前的最后一次相关操作(包括读、seek等操作)设置的。在上述代码while循环中,当fgets
在读取文件最后一行后,文件结束标志还并没有被置位,所以下一次while循环判断依然可以进来,此时再一次调用fgets
将返回null(这时文件结束标志被置位),而line中的字符串保持不变,依然为上一次的结果,此时再一次打印line,所以出现最后一行被打印输出两次。
解决方法:
第一种
#include<stdio.h>
int main()
{
char buff[1024];
memset(buff, 0, sizeof(buff));
FILE* f = fopen("a.txt", "r");
fgets(buff, sizeof(buff), f); // 第一种直接用fgets函数返回结果作while条件判断。
printf("buff is -- %s", buff);
while (!feof(f))
{
printf("---not eof\n");
fgets(buff, sizeof(buff), f);
}
printf("----eof!\n");
return 0;
}
第二种
#include<stdio.h>
int main()
{
char buff[1024];
memset(buff, 0, sizeof(buff));
FILE* f = fopen("a.txt", "r");
fgets(buff, sizeof(buff), f); // 第一种直接用fgets函数返回结果作while条件判断。
printf("buff is -- %s", buff);
while (1)
{
printf("---not eof\n");
fgets(buff, sizeof(buff), f);
if (!feof(f))
printf("buff is -- %s", buff);
else
break;
}
printf("----eof!\n");
return 0;
}
注意
fgets函数的调用会修改文件结束标志,其他还会修改文件结束标志的类似的函数还有:fgetc、fgets、fread、fseek、getc、getchar、gets等,所以,在使用这些函数的时候也要注意这个问题。