Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Compare two files Byte by Byte

I have two binary files and I want to compare them Byte by Byte. I came up with the following code to do so:

int CompareFiles(char *pFname1, char *pFname2)
{
    FILE      *pFile1,*pFile2;
    long      lSize1, lSize2;               // file length
    int       i=0;
    char      tmp1, tmp2;

    pFile1 = fopen(pFname1,"r");
    pFile2 = fopen(pFname2,"r");

    // obtain file size:
    fseek (pFile1 , 0 , SEEK_END);
    lSize1 = ftell (pFile1);
    rewind (pFile1);

    // obtain file size:
    fseek (pFile2 , 0 , SEEK_END);
    lSize2 = ftell (pFile2);
    rewind (pFile2);

    if (lSize1 != lSize2) {
        printf("File sizes differ, %d vs. %d\n",lSize1,lSize2);
        return ( ERROR );
    }
    for (i=0;i<lSize1;i++) {
        fread(&tmp1, sizeof(char), 1, pFile1+i);
        fread(&tmp2, sizeof(char), 1, pFile2+i);
        if (tmp1 != tmp2) {
            printf("%x: tmp1 0x%x != tmp2 0x%x\n",i , tmp1, tmp2);
        }
    }
    return ( OK );
}

But for some reason, it looks like the pointer in the file doesn't advance and it keeps comparing the same Bytes to each other for the whole length of the for loop. Why so? What am I doing wrong here?

like image 810
stdcerr Avatar asked Jan 11 '23 15:01

stdcerr


1 Answers

fread(&tmp1, sizeof(char), 1, pFile1+i);
fread(&tmp2, sizeof(char), 1, pFile2+i);

is changing the file handle for each iteration of the loop. You should use

fread(&tmp1, 1, 1, pFile1);
fread(&tmp2, 1, 1, pFile2);

instead. Each call to fread will advance the file handle's internal pointer to it's file content automatically.

Note that you also log differences in file content but fail to return an error to calling code during your for loop.

If you want to return as soon as you encounter a difference, use

for (i=0;i<lSize1;i++) {
    fread(&tmp1, 1, 1, pFile1);
    fread(&tmp2, 1, 1, pFile2);
    if (tmp1 != tmp2) {
        printf("%x: tmp1 0x%x != tmp2 0x%x\n",i , tmp1, tmp2);
        return ( ERROR ); // report error to caller
    }
}
return ( OK );

If you want to log all differences (this will be potentially very time consuming), use

int err = OK;
for (i=0;i<lSize1;i++) {
    fread(&tmp1, 1, 1, pFile1);
    fread(&tmp2, 1, 1, pFile2);
    if (tmp1 != tmp2) {
        printf("%x: tmp1 0x%x != tmp2 0x%x\n",i , tmp1, tmp2);
        err = ERROR;  // report error to caller
    }
}
return err;
like image 78
simonc Avatar answered Jan 21 '23 17:01

simonc