我是C语言编程的新手,我试图比较2个txt文件中1024个字节的块(目前我正在测试10个字节),并检查其中有多少个块是相同的。
我正在读取带有fread的块并将它们与strcmp进行比较,但是fread从第一个文件读取了两倍,即使我从两个文件中以相同的方式读取也是如此。这就是我的比较功能:
void compareFiles(FILE *fp1, FILE *fp2)
{
char fp1_content[10]; //should be 1024
char fp2_content[10]; //should be 1024
fread(fp1_content, 10, 1, fp1); //should be 1024
fread(fp2_content, 10, 1, fp2); //should be 1024
printf("content of 81.txt %s \n", fp1_content);
printf("content of 82.txt %s \n", fp2_content);
char ch1 = getc(fp1);
char ch2 = getc(fp2);
int eqBlocks = 0;
while (ch1 != EOF && ch2 != EOF)
{
if (strcmp(fp1_content, fp2_content) == 0) {
eqBlocks++;
}
ch1 = getc(fp1);
ch2 = getc(fp2);
fread(fp1_content, 10, 1, fp1);
fread(fp2_content, 10, 1, fp2);
}
printf("Nb of identical blocks: %d\n", eqBlocks);
}
问题来了:我有lorem ipsum文本,两个文件中都有相同的文本。但是前两个printfs正在输出:
content of 81.txt Lorem ipsuLorem ipsu
content of 82.txt Lorem ipsu
为什么第一个加倍?我该如何解决?
答案 0 :(得分:1)
OP的代码需要一些修复。
返回值
诸如fread()
之类的函数返回有用的信息。使用它们。在这种情况下,它告诉您读取了多少。 @Weather Vane
“%s”需要一个字符串指针
printf("content of 81.txt %s \n", fp1_content);
期望fp1_content
是 string 。在C语言中,字符串始终具有 null字符,否则,它不是字符串。要打印可能没有'\0'
的文本,请使用"%.*s"
,它接受一个参数来限制打印长度。带有非字符串的"%s"
是未定义的行为。可能会发生意外的事情。 @Tom Karzes
比较非字符串与memcmp()
不必要的代码
char ch1 = getc(fp1);
不需要检测结尾,请使用fread()
返回值。 @Jean-François Fabre除了:使用int ch1
来区分257个不同的返回值与fgets()
。
避免使用裸魔术数字
不要在各处使用带有10
的乱码,而要使用命名常量。
大胆
文件可以大于INT_MAX
个块。建议long long eqBlocks
。
#include <limits.h>
#define COMPAREFILES_N 10
#if COMPAREFILES_N > INT_MAX
#error Use smaller block
#endif
void compareFiles(FILE *fp1, FILE *fp2) {
char fp1_content[COMPAREFILES_N];
char fp2_content[COMPAREFILES_N];
long long eqBlocks = 0;
for (;;) {
size_t len1 = fread(fp1_content, COMPAREFILES_N, 1, fp1);
size_t len2 = fread(fp2_content, COMPAREFILES_N, 1, fp2);
if (len1 < 1 || len2 < 1) {
break; // failed to read a block in each file
}
if (memcmp(fp1_content, fp2_content, COMPAREFILES_N) == 0) {
eqBlocks++;
printf("Common content `%.*s`\n", COMPAREFILES_N, fp1_content);
}
}
printf("Nb of identical blocks: %lld\n", eqBlocks);
}