• 文件读取结束的判定


    大家好啊,我们今天来补充文件操作的读取结束的判定。

    在这里插入图片描述

    被错误使用的feof

    牢记:在文件读取过程中,不能用feof函数的返回值直接用来判断文件的是否结束而是应用于当文件读取结束的时候,判断是读取失败结束,还是遇到文件尾结束。

    1. 文本文件读取是否结束,判断返回值是否为 EOF ( fgetc ),或者 NULL ( fgets )
      例如:
      fgetc 判断是否为 EOF .
      fgets 判断返回值是否为 NULL .
    2. 二进制文件的读取结束判断,判断返回值是否小于实际要读的个数。 例如: fread判断返回值是否小于实际要读的个数。

    【看到代码】

    #include 
    #include 
    int main(void)
    {
    int c; // 注意:int,非char,要求处理EOF
    FILE* fp = fopen("test.txt", "r");
    if(!fp) {
    perror("File opening failed");
    return EXIT_FAILURE;
    }
    //fgetc 当读取失败的时候或者遇到文件结束的时候,都会返回EOF
    while ((c = fgetc(fp)) != EOF) // 标准C I/O读取文件循环
    {
    putchar(c);
    }
    //判断是什么原因结束的
    if (ferror(fp))
    puts("I/O error when reading");
    else if (feof(fp))
    puts("End of file reached successfully");
    fclose(fp);
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22

    还有一个就是文件缓冲区:

    ANSIC 标准采用“缓冲文件系统”处理的数据文件的,所谓缓冲文件系统是指系统自动地在内存中为程序中每一个正在使用的文件开辟一块“文件缓冲区”。从内存向磁盘输出数据会先送到内存中的缓冲区,装满缓冲区后才一起送到磁盘上。如果从磁盘向计算机读入数据,则从磁盘文件中读取数据输入到内存缓冲区(充满缓冲区),然后再从缓冲区逐个地将数据送到程序数据区(程序变量等)。缓冲区的大小根据C编译系统决定的。

    在这里插入图片描述

    那么我们怎么来判断文件缓冲区呢?

    #include 
    #include 
    //VS2013 WIN10环境测试
    int main()
    {
    FILE*pf = fopen("test.txt", "w");
    fputs("abcdef", pf);//先将代码放在输出缓冲区
    printf("睡眠10秒-已经写数据了,打开test.txt文件,发现文件没有内容\n");
    Sleep(10000);
    printf("刷新缓冲区\n");
    fflush(pf);//刷新缓冲区时,才将输出缓冲区的数据写到文件(磁盘)
    //注:fflush 在高版本的VS上不能使用了
    printf("再睡眠10秒-此时,再次打开test.txt文件,文件有内容了\n");
    Sleep(10000);
    fclose(pf);
    //注:fclose在关闭文件的时候,也会刷新缓冲区
    pf = NULL;
    return 0;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19

    这里我们以写的方式打开一个文件,在其中写入abcdef,睡眠十秒当我们发现文件里并没有内容,这个时候我们刷新缓冲区睡眠十秒,这个时候我们的才将缓冲区上的内容写到文件里,我们再打开文件就可以看到我们文件上的内容了。

    相信大家一定明白了原理,那么我们的分享就到这里了,谢谢大家。

  • 相关阅读:
    STM32CubeMX实战教程(九)——外部SRAM+内存管理
    SpringBoot 3.0 来啦!
    力扣:11-盛最多水的容器
    聊聊MySQL的10大经典错误
    页面关闭前,如何发送一个可靠请求
    C++面向对象语言自制多级菜单
    代码随想录算法训练营第二十一天 | LeetCode 235. 二叉搜索树的最近公共祖先、701. 二叉搜索树中的插入操作、450. 删除二叉搜索树中的节点
    SpringBoot,ModelAndView重定向
    设计模式笔记之装饰器模式(结构型)
    python+robotframework接口自动化测试
  • 原文地址:https://blog.csdn.net/Lehjy/article/details/133970205