很基本也很诡异的fread, feof

先看一段非常简单的程序:
 
#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。就这么一个小小的误解,让我调了一天,才找到程序错误的真正原因。

你可能感兴趣的:(FP)