C语言文件对比代码为何能正确识别文件长度差异?
我的C语言文件对比函数为何能正确工作?
先看你写的对比函数代码:
int cmp_f(char *filename1, char *filename2) { int c1, c2; FILE *file1 = NULL; FILE *file2 = NULL; file1 = fopen(filename1, "r"); file2 = fopen(filename2, "r"); if (file1 == NULL || file2 == NULL) { printf("Error occured while reading files.\n"); fclose(file1); fclose(file2); return -1; } while ((c1 = fgetc(file1)) != EOF) { c2 = fgetc(file2); if (c1 != c2) { fclose(file1); fclose(file2); return 0; } } fclose(file1); fclose(file2); return 1; }
你的测试场景是:
foo@linux:~$ cat file1.txt This is txt file. foo@linux:~$ cat file2.txt This is txt file.!!!
你疑惑的点是:以为file1读到EOF时,fgetc(file2)不会执行,file2更长应该返回1,但实际返回0。
为什么你的测试场景会返回0?
问题出在文件的隐藏换行符上:
当你用cat查看文件时,输出的内容末尾会自动换行,但实际文件里,file1.txt的内容是This is txt file.\n(结尾包含换行符),而file2.txt的内容是This is txt file.!!!\n。
循环执行到最后几步时:
- 读取
file1的最后一个可见字符.,和file2的.对比,相等; - 下一次循环,
c1 = fgetc(file1)读取到换行符\n,不是EOF,进入循环; - 执行
c2 = fgetc(file2),读取到的是第一个!; \n和!不相等,触发返回0的逻辑,所以函数返回0,判定为不同。
这就是为什么你的测试会得到正确结果的原因——你忽略了文件结尾的换行符,实际上两个文件在对应位置的字符已经不一样了。
代码的潜在bug
不过你的代码并非完全正确,它存在一个逻辑漏洞:如果file1确实比file2短,且前面所有字符完全一致(包括结尾的换行符),那么当file1读完后,循环直接结束,函数返回1,不会检查file2是否还有剩余字符。
比如:
file1.txt内容:abc\nfile2.txt内容:abc123\n
此时函数会错误返回1,判定两个文件相同,但实际上file2有额外内容。
修复方案
要解决这个漏洞,在循环结束后,需要额外检查file2是否已经读到EOF:
// 原循环结束后添加 c2 = fgetc(file2); if (c2 != EOF) { fclose(file1); fclose(file2); return 0; }
这样就能覆盖file2比file1长的场景,确保所有情况都能正确判定。
内容的提问来源于stack exchange,提问作者Beomsoo Kim
相关产品推荐
相关产品推荐

