C语言中用feof()读取数据文件时重复输出最后一行的问题
为什么你的程序会重复打印最后一行?
这是C语言里使用feof()判断文件结束的经典误区,很多新手都会踩这个坑!
问题根源
feof()的工作逻辑和你想的不一样:它不会在文件指针到达文件末尾时立刻返回真,而是要等你尝试从已经到末尾的位置读取数据,并且读取失败之后,才会设置文件结束的标志位,这时候feof()才会返回非零值。
回到你的代码流程:
- 当程序读完最后一组4个数值后,文件指针已经到了文件末尾,但此时
feof(f)仍然返回假,所以循环继续执行。 - 接下来执行
fscanf(f,"%lf%lf%lf%lf",&x,&y,&z,&t),这时候因为已经到了文件末尾,读取失败,但x、y、z、t里还保留着上一次读取的最后一行数据。 - 然后你执行
printf,就把这些旧数据又打印了一遍。 - 这时候
feof(f)才会检测到文件结束,触发break退出循环。
正确的写法
你应该直接用fscanf()的返回值来判断读取是否成功——fscanf()会返回成功读取的参数个数,这里你每次要读4个double,所以只要返回值等于4,就说明读取有效,继续循环;否则就退出。
修改后的代码如下:
#include <stdio.h> #include <stdlib.h> int main() { FILE *f = fopen("tdat.dat","r"); if (f == NULL) { // 一定要检查文件是否成功打开! perror("Failed to open file"); return EXIT_FAILURE; } double x, y, z, t; int ret; // 用fscanf的返回值判断读取是否成功 while ((ret = fscanf(f,"%lf%lf%lf%lf",&x,&y,&z,&t)) == 4) { printf("%lf\t%lf\t%lf\t%lf\n",x,y,z,t); } // 可选:用feof区分是文件结束还是读取错误 if (!feof(f)) { printf("Warning: Unexpected read error or invalid data in file\n"); } fclose(f); // 读完文件别忘关闭,避免资源泄漏 return EXIT_SUCCESS; }
额外提醒
- 永远不要忽略文件打开失败的判断,否则会导致未定义行为。
feof()的正确使用场景是:当读取操作失败后,用来判断失败原因是到达文件末尾,还是发生了其他IO错误(比如磁盘故障)。
内容的提问来源于stack exchange,提问作者Lê Dũng
相关产品推荐
相关产品推荐

