【被误用的feof与文件操作读取结束的正确判定】
- 游戏开发
- 2025-08-17 10:00:01

学习导航 一、被误用的feof
从函数的名字来看,大家很容易把函数的功能理解成:检测是是否达到文件的结尾。但事实真的如此吗?我们首先来查阅feof函数的返回值:
所以可以确定的是,如果feof检测出文件结束志标记则返回一个非零值。但这里需要注意,feof检测的是 “文件结束标记” ,而不是 “文件位置标记” ,这在FILE结构体中属于两种不同的标记。文件到达结尾只是说明文件的位置标记达到末尾,不能说明文件结束标记的情况,而只有文件结束标记才能使feof的返回值为真。 我们可以用下面的代码来说明上面的结论,预先使test.txt的内容为空。
int main() { FILE* fp = fopen("test.txt", "r"); if (fp == NULL) { printf("%s", strerror(errno)); return 0; } for (int i = 0; i < 2; i++) { printf("feof() = %d\n", feof(fp)); fgetc(fp); } fclose(fp); fp = NULL; return 0; }打印结果如下:
feof() = 0; feof() = 1; 可以看到即使到达了文件结尾,feof也不能立刻检测出。那为什么第二次就可以呢?其实原因在于fgetc发挥了作用。根据C标准对该函数的说明,当fgetc返回值为EOF时且确实已经到达文件结尾时(返回值为EOF可能有其他的情况),fgetc函数会自动设置文件结束标记。
所以换言之,feof函数并不能检测是否达到文件结尾,它只能测出文件读取失败是否由于文件读取结束引起的。文件读取失败对于fgetc函数来说表现在返回值为EOF。
二、正确的判断方法正确的做法是根据函数的返回值来进行判断,现在我们对常用函数进行逐一说明:
①fgetc函数fgetc函数需要检测返回值是否为EOF 如果到达文件结尾,文件结束标志被fgetc函数设置,可以通过feof函数检测出 如果发生读取错误,文件错误标志被fgetc函数设置,可以通过ferror函数检测出
int main() { FILE* fp = fopen("test.txt", "r"); if (fp == NULL) { printf("%s", strerror(errno)); return 0; } int c = 0; while ((c = fgetc(fp)) != EOF) { putchar(c); } //判断是什么原因结束的 if (ferror(fp)) { printf("I/O error when reading\n"); } else if (feof(fp)) { printf("End of file reached successfully\n"); } flose(fp); fp = NULL; return 0; } ②fgetsfgets函数需要检测返回值是否为NULL 如果到达文件结尾,文件结束标志被fgets函数设置,可以通过feof函数检测出 如果发生读取错误,文件错误标志被fgets函数设置,可以通过ferror函数检测出
③fread函数对于fread函数我们需要检测实际返回的读取个数和预期读取个数 如果实际读取个数和预期读取个数不同,说明要么发生读取错误,要么达到文件结尾,那么相应的文件错误标志和文件结束标志也被设置。可以通过ferror和feof函数进行检验。
#define SIZE 5 int main(void) { double src[SIZE] = { 1.0, 2.0, 3.0, 4.0, 5.0 }; double buf[SIZE] = {0}; FILE* fp = fopen("test.bin", "wb"); // 必须用二进制模式 fwrite(src, sizeof(src[0]), SIZE, fp); // 写 double 的数组 fclose(fp); fp = fopen("test.bin", "rb"); size_t ret_code = fread(buf, sizeof(buf[0]), SIZE, fp); // 读 double 的数组 if (ret_code == SIZE) { puts("Array read successfully, contents: "); for (int n = 0; n < SIZE; ++n) printf("%f ", buf[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; } 三.总结**fgetc、fgets、fread才是判断文件是否读取结束的,
如果fgetc返回EOF则文件读取结束,否则没结束返回当前文件位置标记的ASCII码值。如果fgets返回NULL则文件读取结束,否则返回当前文件位置标记的地址如果fread返回的实际值即读的实际个数小于预期读的个数说明读取结束,否则没有读取结束**但是上面三种方式都只是判断文件是否读取结束,但是并不知道是正常读取结束还是异常导致的读取结束,所以我们要通过feof来判断,如果返回非0值,是正常读取结束,否则是异常读取结束,用ferror来打印错误信息。
小编制作不易,点个小猪猪,谢谢大家!
【被误用的feof与文件操作读取结束的正确判定】由讯客互联游戏开发栏目发布,感谢您对讯客互联的认可,以及对我们原创作品以及文章的青睐,非常欢迎各位朋友分享到个人网站或者朋友圈,但转载请说明文章出处“【被误用的feof与文件操作读取结束的正确判定】”
上一篇
两数之和[中等]
下一篇
vue3使用腾讯地图选择地点