Другие проблемы, связанные со сравнением файлов, которые еще не рассмотрены в ответах
Файл данных с '\0'
Если файл содержит нулевой символ , fgets()
будет читать этот символ, как и любой другой символ не в конце строки. Тогда следующий strcmp()
будет не сравнивать всю прочитанную строку. Лучше использовать fread()/memcmp()
, чтобы избежать этого недолгого.
Сравнение как текстовое или двоичное?
Открытие файла с помощью "r"
, как и в fopen(file_1,"r")
, допускает различные переводы: конец строки, конец файла, метки порядка байтов.
Открытие с "r"
имеет смысл сравнивать как text . В противном случае откройте файл в двоичном режиме "rb"
. Используйте fread()
в любом случае.
Строка текста с "\r\n"
в одном файле и строка текста с "\n"
в другом файле могут сравниваться в режиме text , но могут отличаться в режиме binary .
Поскольку запись помечена как [linux], в режиме text не ожидается перевода.
несопоставимо
Во время чтения может произойти ошибка ввода, приводящая к спору сравнения.
Пример сравнительного кода
#include <stdbool.h>
#include <stdio.h>
#define FILE_COMPARE_N 1024
// 1: match
// 0: mis-match
// -1: failure
int stream_compare(FILE *f1, FILE *f2) {
unsigned char buf1[FILE_COMPARE_N];
unsigned char buf2[FILE_COMPARE_N];
size_t l1, l2;
do {
l1 = fread(buf1, sizeof buf1[0], FILE_COMPARE_N, f1);
if (ferror(f1))
return -1;
l2 = fread(buf2, sizeof buf2[0], FILE_COMPARE_N, f2);
if (ferror(f2))
return -1;
if (l1 != l2 || memcmp(buf1, buf2, l1) != 0)
return 0; // mis-match
} while (l1);
return 1; //match
}
int file_compare(const char *name1, const char *name2, bool as_text) {
FILE *f1 = fopen(name1, as_text ? "rb" : "r");
if (f1 == NULL)
return -1;
FILE *f2 = fopen(name2, as_text ? "rb" : "r");
if (f2 == NULL) {
fclose(f1);
return -1;
}
int compare = stream_compare(f1, f2);
fclose(f1);
fclose(f2);
return compare;
}