我编写了这种方法,用于比较两个文件,特别是图片,并在输出中打印差异在哪里以及差异是什么。此时,这样做的结果是每个字节都不同,但我正在比较的图像是相同的。你能帮我吗?这是代码:
void compareFiles(char* path1, char* path2){
FILE* img1;
FILE* img2;
if((img1 = fopen(path1,"r")) == NULL || (img2 = fopen(path2,"r")) == NULL){
printf("ERROR fopen()n");
exit(-1);
}
int i=0;
char buffer1,buffer2;
int c;
while ((c=fgetc(img1)) != EOF){
fread(&buffer1, 1,1, img1);
fread(&buffer2, 1,1, img2);
if(buffer1 != buffer2){
printf("Byte differsn IMG1: %s, IMG2: %s; Position %dn",&buffer1,&buffer2,i);
i++;
}
}
fclose(img1);
fclose(img2);
}
while ((c=fgetc(img1)) != EOF)
这将读取img1
的第一个字节。 假设它不是EOF
...
fread(&buffer1, 1,1, img1);
这将读取img1
的第二个字节。
fread(&buffer2, 1,1, img2);
这将读取img2
的第一个字节。
if(buffer1 != buffer2)
所以现在我们正在比较img2
的第一个字节和img1
的第二个字节。
如果它们碰巧相等,我们将再次循环,最终将img2
的第二个字节与img1
的第四个字节进行比较。
看起来您可能认为fgetc
测试以查看是否有另一个字节可用,然后fread
读取它。 但是没有。fgetc
从文件中读取一个字符,然后将其返回。 如果你写
c = fgetc(fp);
它几乎和你写的完全一样
fread(&c, 1, 1, fp);
因此,对程序的最小修复是摆脱
fread(&buffer1, 1,1, img1);
行,并将相等性检验更改为
if(c != buffer2)
但这最终有点令人困惑 - 后来的读者可能会想知道,"为什么一个文件使用fgetc
读取,而另一个文件使用fread
?
如果我写这篇文章,我可能会使用getc
从img1
中读取一个字节,使用getc
从img2
读取一个字节,并比较它们。 或者,我可以使用fread
将 N 个字节从img1
读取到字符数组中,将 N 个字节从img2
读取到第二个字符 adday 中,并使用memcmp
函数进行比较。
此外,正如Paul Ogilvie在评论中提到的,由于这些是二进制文件,因此当您调用fopen
打开它们时,您应该指定"rb"
模式。
在我看来,您应该将它们转换为两个位图并进行标题和矩阵比较。您现在遇到了麻烦,因为标头和标记可能不同。您可以找到许多有关此主题的教程,例如有关代码项目的教程。
正如其他评论中所述,fgetc 正在从流中读取一个字符,因此在调用 fread 之前,2 个流是不同步的。下面使用 2 次调用 fgetc,然后使用返回值进行比较。
void compareFiles(char* path1, char* path2){
FILE* img1;
FILE* img2;
if((img1 = fopen(path1,"rb")) == NULL || (img2 = fopen(path2,"rb")) == NULL){
printf("ERROR fopen()n");
exit(-1);
}
int i=0;
int byte1,byte2;
while (((byte1=fgetc(img1)) != EOF) && ((byte2=fgetc(img2)) != EOF)){
if(byte1 != byte2){
printf("Byte differsn IMG1: %c, IMG2: %c; Position %dn",byte1,byte2,i);
i++;
}
}
fclose(img1);
fclose(img2);
}