三、文件结束的判定:
1.错误使用 feof 函数:
在一段时间的交流中,我发现有很多小伙伴们都错误的使用了 feof 函数,将其用于判断文件是否读取结束 ,而这种使用方式是错误的。
我们应该记住:
在文件的读取过程中,不能通过 feof 函数的返回值来判定文件是否读取结束。
该函数的作用为:在已经确定文件读取结束的情况下,用于判定文件读取结束的原因
2.一些判断文件结束的总结:
2.1. 文本文件读取是否结束:
要判断返回值是否为 EOF ( fgetc ),或者 NULL ( fgets )
例如:
fgetc 判断是否为 EOF .
fgets 判断返回值是否为 NULL .
int main() { int c; //注意:int,非char,要求处理EOF FILE* fp = fopen("test.txt", "r"); if (!fp) { perror("File opening failed"); return 1; } // 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); fp = NULL; return 0; }
2.2. 二进制文件的读取结束判断,
判断返回值是否小于实际要读的个数。
例如:
fread判断返回值是否小于实际要读的个数。
#include<stdio.h> enum { SIZE = 5 }; int main(void) { double a[SIZE] = { 1.,2.,3.,4.,5. }; FILE* fp = fopen("test.bin", "wb"); //必须用二进制模式 fwrite(a, sizeof * a, SIZE, fp); //写 double 的数组 fclose(fp); double b[SIZE]; fp = fopen("test.bin", "rb"); size_t ret_code = fread(b, sizeof * b, SIZE, fp); //读 double 的数组 //判断是否读取成功 if (ret_code == SIZE) { puts("Array read successfully, contents: "); for (int n = 0; n < SIZE; ++n) printf("%f ", b[n]); putchar('\n'); } //寻找读取失败的原因: else { // error handling if (feof(fp)) { printf("Error reading test.bin: unexpected end of file\n"); } else if (ferror(fp)) { perror("Error reading test.bin"); } } fclose(fp); fp = NULL; return 0; }
3.判断原因的两个函数:
四、缓冲区的简单介绍
文件缓冲区是用以暂时存放读写期间的文件数据而在内存区预留的一定空间。
ANSIC 标准采用“缓冲文件系统”处理的数据文件的,所谓缓冲文件系统是指系统自动地在内存中为程序中每一个正在使用的文件开辟一块“文件缓冲区”.从内存向磁盘输出数据会先送到内存中的缓冲区,装满缓冲区后才一起送到磁盘上。如果从磁盘向计算机读入数据,则从磁盘文件中读取数据输入到内存缓冲区(充满缓冲区),然后再从缓冲区逐个地将数据送到程序数据区(程序变量等)。缓冲区的大小根据C编译系统决定的。
要使缓冲区的内容进入内存或者计算机硬盘有两种方法,第一种是缓冲区充满自动填入,第二个是主动刷新缓冲区。
举个例子:
#include <stdio.h> #include <Windows.h> //VS2022 WIN10环境测试 int main() { FILE* pf = fopen("test.txt", "w"); fputs("abcdef", pf); //先将代码放在输出缓冲区 printf("睡眠10秒\n"); //已经写数据了,但是打开test.txt文件,发现文件没有内容 Sleep(10000); printf("刷新缓冲区\n"); fflush(pf); //刷新缓冲区时,才将输出缓冲区的数据写到文件(磁盘) //注:fflush 在高版本的VS上不能使用了 printf("再睡眠10秒\n"); //此时,再次打开test.txt文件,文件有内容了 Sleep(10000); fclose(pf); //注:fclose在关闭文件的时候,也会刷新缓冲区 pf = NULL; return 0; }
所以在这里,各位小伙伴们一定要注意了,因为缓冲区的存在,数据只有在填满缓冲区后才会进行真正的写入或读取,所以在 C 语言程序代码的编写过程中,我们一定要在文件操作结束时关闭文件,否则就可能导致文件的读写操作出现问题。
总结:
经过今天内容的补充,我们关于文件操作与管理的知识就全部学完了,不知道小伙伴们是否掌握了呢?
更新不易,辛苦各位小伙伴们动动小手,👍三连走一走💕💕 ~ ~ ~ 你们真的对我很重要!最后,本文仍有许多不足之处,欢迎各位认真读完文章的小伙伴们随时私信交流、批评指正!