先看一段非常简单的程序:
#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 就完全可以实现,使用如下代码:
当 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。就这么一个小小的误解,让我调了一天,才找到程序错误的真正原因。