`
febird
  • 浏览: 254248 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

很基本也很诡异的fread, feof

    博客分类:
  • C++
FP 
阅读更多
先看一段非常简单的程序:
 
#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。就这么一个小小的误解,让我调了一天,才找到程序错误的真正原因。
0
0
分享到:
评论

相关推荐

    feof函数多读一次问题分析

    在探讨“feof函数多读一次问题分析”这一主题时,我们首先需要理解feof函数的基本功能以及它在文件读取过程中的作用。feof(File End Of File)函数是C语言标准库中的一个函数,用于检测文件指针是否到达了文件末尾...

    为什么fread(),fwrite()的返回值总是为0,但是读写文件正常

    2. **文件结束**:`fread()` 在读到文件末尾时也会返回0。如果试图读取超过文件实际长度的数据,返回值将是从当前文件位置到文件末尾的实际字节数。 3. **错误条件**:如果文件流有错误(比如打开失败、权限问题等...

    php feof用来识别文件末尾字符的方法

    总的来说,理解并正确使用`feof()`是PHP开发中处理文件的基本技能之一。确保在使用`feof()`时进行适当的错误检查和资源验证,可以提高代码的健壮性和可靠性。同时,熟悉其他文件操作函数和类,如`SplFileObject`,...

    C语言读取文件流的相关函数用法简介

    C语言读取文件流相关函数用法简介 C语言中读取文件流的相关函数用法简介是非常重要的知识点,对于...fread()函数和feof()函数是C语言读取文件流的基本函数,master这些函数可以帮助开发者更好地读取和处理文件流数据。

    文件读写数据转换

    `fread` 函数用于从文件中读取数据,其基本语法为: ```c size_t fread(void *ptr, size_t size, size_t nmemb, FILE *stream); ``` `ptr` 指向接收读取数据的内存位置,`size` 定义每个元素的大小,`nmemb` 是要...

    C语言中操作文件的基本方法.pdf

    除了基本的读写操作,还有其他高级文件操作,如文件定位(`fseek()`)、文件状态检查(`feof()`、`ferror()`)、文件重命名(`rename()`)等。理解并熟练掌握这些操作对开发复杂的C语言程序至关重要,特别是涉及数据...

    c语言文件操作常用函数及读写文件代码举列

    其基本语法为:size_t fread(void *ptr, size_t size, size_t nmemb, FILE *fp),其中ptr是读取的缓冲区,size是每个元素的大小,nmemb是元素个数,fp是文件指针。 15. fwrite()函数:向流中写指定个数的字符 ...

    C语言中进行文件读写操作的基本代码示例.zip

    总结来说,C语言中的文件操作涉及到文件的打开、读取、写入和关闭,主要使用`fopen()`、`fread()`、`fwrite()`、`fscanf()`、`fprintf()`、`fseek()`、`ftell()`、`feof()`、`ferror()`和`fclose()`等函数。...

    PHP读取文件的正确方法.docx

    本文主要探讨了使用fopen、feof、fclose以及fgets和fread等函数来读取文件的基本步骤和注意事项。 首先,`fopen()`函数是PHP中打开文件的关键。它接受两个参数:文件路径和模式。例如,`fopen("myfile", "r")`会以...

    C语言基本库函数大全

    5. **文件操作(File Handling)**:fopen、fclose打开和关闭文件,fread、fwrite读写二进制数据,fgets、fputs读写文本数据,feof检查是否到达文件结束。 6. **错误处理(Error Handling)**:errno全局变量记录...

    模拟实现单级目录的FAT文件系统.pdf

    * 文件块读:int FREAD(void *ptr, int n, int fileid); * 文件块写:int FWRITE(void *ptr, int n, int fileid); * 判断文件结束:int FEOF(int fileid); * 获取文件指针:long FGETPOS(int fileid); * 设置文件...

    C语言基本库函数——C.pdf

    - `fopen` 打开文件,`fclose` 关闭文件,`fread` 和 `fwrite` 读写文件内容。 - `feof` 检查文件是否到达末尾,`ferror` 检查文件操作是否有错误。 7. 其他常用函数: - `exit` 结束程序,`abort` 强制终止程序...

    matlab初学者应学习操作基本命令.doc

    `fopen`、`fclose`分别用于打开和关闭文件,`fread`、`fwrite`读写二进制数据,`fscanf`、`fprintf`进行格式化数据的读写,`fgetl`、`fgets`读取文件行,`ferror`检查错误,`feof`检测文件是否结束,`fseek`设置文件...

    文件IO 文件操作 操作文件 标准IO和文件IO

    在文件IO中,还有一些其他的函数,例如fclose函数用来关闭文件,feof函数用来判断文件是否结束,fseek函数用来将文件指针移到指定的位置等。 文件IO是计算机系统中最基本的输入/输出操作之一,它提供了一些基本的...

    C语言二进制文件处理

    #### 一、二进制文件处理的基本概念 在C语言中处理文件时,通常有两种模式:文本模式和二进制模式。这两种模式的主要区别在于对数据的解释方式不同。文本模式主要用于处理文本文件,而二进制模式则适用于所有类型的...

    MATLAB之文件Io.docx

    最基本的调用形式为:a=fread(fid)其中,fid 是从 fopen 中得来的文件标识。MATLAB 读取整个文件并将文件指针放在文件末尾处(在后面的 feof 命令介绍中有详细解释)。 其他相关函数 * ferror:用于获取文件打开...

    matlab基本命令.docx

    - 使用 Workspace 浏览器也可以查看变量信息。 - `delete &lt;文件名&gt;`:从磁盘中删除指定文件。 - `which &lt;文件名&gt;`:查找指定文件的完整路径。 - `clear all`:清除工作空间中的所有变量和函数。 - `help &lt;命令...

    在线学生管理系统笔记1

    `fwrite()` 和 `fread()`,以及文件结束检测函数 `feof()`。 1. **_getch() 与 getch() 区别** 在C语言中,`getch()` 是用于从标准输入读取单个字符的函数,通常用于控制台程序中获取用户输入。带下划线的 `_getch...

    数学建模 文件操作 基本命令 文件的打开与关闭

    接着,`fread`用于读取二进制数据文件,如`[A,COUNT]=fread(Fid,size,precision)`,`A`为数据矩阵,`COUNT`为读取的元素数,`size`和`precision`定义读取的大小和精度。`fwrite`则用于写入二进制数据,`fprintf`和`...

Global site tag (gtag.js) - Google Analytics