Сравните два файла побайтно

У меня есть два двоичных файла, и я хочу сравнить их побайтно. Для этого я придумал следующий код:

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 );
}

Но по какой-то причине кажется, что указатель в файле не продвигается вперед и продолжает сравнивать одни и те же байты друг с другом на протяжении всей длины цикла for. Почему так? Что я здесь делаю неправильно?


person stdcerr    schedule 19.12.2013    source источник
comment
Совет: используйте memcmp вместо перебора каждого байта: cplusplus.com/reference/ cstring/memcmp/?kw=memcmp   -  person Ramy Al Zuhouri    schedule 19.12.2013


Ответы (1)


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

меняет дескриптор файла для каждой итерации цикла. Вы должны использовать

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

вместо. Каждый вызов fread автоматически перемещает внутренний указатель дескриптора файла на его содержимое.

Обратите внимание, что вы также регистрируете различия в содержимом файла, но не возвращаете ошибку вызывающему коду во время цикла for.

Если вы хотите вернуться, как только обнаружите разницу, используйте

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 );

Если вы хотите регистрировать все различия (это может занять очень много времени), используйте

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;
person simonc    schedule 19.12.2013
comment
Итак, как мне переместить указатель файла, когда я хочу сравнить каждый байт? к вашему сведению, я сравниваю каждый байт и печатаю сообщение, если они различаются, что именно вы имеете в виду? - person stdcerr; 19.12.2013
comment
Убедитесь, что вы удалили эту ошибку pFile1+i из расширенных баллов. - person Till; 20.12.2013