Fread从文件读取双倍

时间:2019-05-26 19:53:30

标签: c compare fread strcmp

我是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

为什么第一个加倍?我该如何解决?

1 个答案:

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