ARTICLE DETAIL

资讯详情

深耕网站视觉设计与运营推广的一线实战洞察。

C语言经典Bug:feof 导致文件复制最后一行重复

C语言经典Bug:feof 导致文件复制最后一行重复 一、问题现象在使用feof()配合文件逐行拷贝时很多初学者都会遇到同一个诡异问题文件拷贝成功但目标文件的最后一行被重复复制了一遍。该问题不是逻辑写错而是对feof 的触发机制理解错误。二、核心前置原理必背1.EOF 标记不会自动触发文件指针走到末尾feof 仍然为假。2.EOF 只有在读函数读取失败后才会置位fgets / fread / fgetc。3.读取失败不会清空缓冲区数组会保留上一次读到的旧内容。三、错误代码先判断feof后读取 → 出现重复行#include stdio.h int main() { FILE *fp fopen(1.txt,r); if(fp NULL) { perror(fopen failed); return -1; } FILE *fp_1 fopen(2.txt,w); if(fp_1 NULL) { perror(fopen_1 failed); fclose(fp); return -1; } char s[4096]; // 错误顺序先判断EOF → 再读 → 再写 while(1) { if(feof(fp)) { break; } fgets(s,sizeof(s),fp); fputs(s,fp_1); } fclose(fp); fclose(fp_1); return 0; }四、错误流程完整解析产生重复行原因步骤1正常读取并写入最后一行程序读取文件最后一行有效数据写入 2.txt文件指针走到文件末尾。此时没有读取失败EOF 标记依旧为假。步骤2进入下一轮循环feof 不成立虽然指针已经在末尾但因为没有发生读取失败feof 返回 false不会退出循环。步骤3执行 fgets读取失败EOF 置位指针在末尾无数据可读fgets 读取失败。系统将 EOF 标记置为 true。但缓冲区数组 s 保留着上一轮的最后一行旧数据。步骤4执行 fputs重复写入最后一行程序没有判断读取是否成功直接把缓冲区残留的旧内容再次写入文件末尾多出一行重复内容。步骤5下一轮循环退出再次循环时 feof 为真跳出循环但重复数据已经写入完成。五、正确代码保留 feof 结构先读 → 后判断 → 再写入#include stdio.h int main() { FILE *fp fopen(1.txt,r); if(fp NULL) { perror(fopen failed); return -1; } FILE *fp_1 fopen(2.txt,w); if(fp_1 NULL) { perror(fopen_1 failed); fclose(fp); return -1; } char s[4096]; // 正确顺序先读 → 判断EOF → 再写入 while(1) { fgets(s,sizeof(s),fp); if(feof(fp)) { break; } fputs(s,fp_1); } fclose(fp); fclose(fp_1); return 0; }六、正确流程解析无重复行1. 正常内容读取成功、feof 为假、正常写入。2. 读到文件末尾fgets 读取失败EOF 标记置位。3. 立刻判断 feof直接 break。4.不会执行 fputs旧数据不会二次写入彻底解决重复 Bug。七、最终结论重点考点1.feof 不能预判末尾只能检测是否读失败。2. 使用 while(1)feof 结构必须先读、后判断。3. 先判断再读取100% 出现最后一行重复。4. 工程开发推荐最简稳定写法无需 feofwhile(fgets(s, sizeof(s), fp) ! NULL) { fputs(s, fp_1); }
返回列表