先看一段非常简单的程序:
#include <stdio.h>
int main(int argc, char** argv)
{
char buf[8193];
FILE* fp = fopen("tmp.bin", "wb+");
fwrite(buf, 1, 8192, fp);
fseek(fp, 0, 0);
fread(buf, 1, 8193, fp);
/* here, all are ok, feof(fp) returns !0
*/
printf("8193, feof(fp)=%d\n", feof(fp));
fseek(fp, 0, 0);
fread(buf, 1, 8192, fp);
/* should feof(fp) return 0 or not? a true implementation should return 0
but now it is eof
*/
printf("8192, feof(fp)=%d\n", feof(fp));
fclose(fp);
return 0;
}
怎样在第二种情况下(8192)取得正确的 feof ?
问题在于,只有当 fread requested < actual_read 时,下一个 feof 才会返回 true ,而不管 filepointer 是否达到了 fileend。
当 fread requested == actual_read 时并且 fileptr 也确实到了文件末尾,feof 却不会返回 true ,
这样的话,feof 基本上就相当于一个摆设,它的功能 fread 就完全可以实现,使用如下代码:
for(;;)
{
size_t bytes_read = fread(buf, 1, bytes_requested, fp);
if (bytes_read == bytes_requested)
{
/* do something 1*/
}
else if (bytes_read < bytes_requested)
{
/* do something 2*/
break;
}
}
根本就不需要 feof ! feof 能做的,fread 完全可以做,fread做不了的,feof也做不了!
feof 的唯一用处就是:当fread 时
bytes_read < bytes_requested 并且 下一个feof返回了false,这表明文件发生了一个错误:
for(;;)
{
size_t bytes_read = fread(buf, 1, bytes_requested, fp);
if (bytes_read == bytes_requested)
{
/* do something 1*/
}
else if (bytes_read < bytes_requested)
{
if (feof(fp))
{
/* now, it is end of file */
}
else
{
/* now, it is an error on fp */
}
break;
}
}
这样一来,feof 的这个唯一作用是用来检查文件错误,而非 end of file。这种情况下,使用 ferror 能更准确地表达意图:
for(;;)
{
size_t bytes_read = fread(buf, 1, bytes_requested, fp);
if (bytes_read == bytes_requested)
{
/* do something 1*/
}
else if (bytes_read < bytes_requested)
{
if (ferror(fp))
{
/* now, it is an error on fp */
}
else
{
/* now, it is end of file */
}
break;
}
}
然而,就是因为 stdio.h 中有一个 feof,让我错误地以为 feof 必定会在 filepointer 到达 fileend 时返回 true。就这么一个小小的误解,让我调了一天,才找到程序错误的真正原因。