Fread 从文件中读取两次

Fread reads double from a file

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

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

OP 的代码需要一些修复。

Return值

fread()return 等函数有用的信息。使用它们。在这种情况下,它会告诉您读取了多少。

"%s" 需要一个 string pointer

printf("content of 81.txt %s \n", fp1_content); 期望 fp1_content 是一个 字符串 。在 C 中,一个 string 总是有一个 null character,否则,它不是一个字符串。要打印可能没有 '[=14=]' 的文本,请使用 "%.*s",它接受一个参数来限制打印长度。 "%s" 和 non-string 是 未定义的行为 。可能会发生意想不到的事情。

比较 non-strings 与 memcmp()

不必要的代码

char ch1 = getc(fp1);不需要检测结束,使用fread()return值。 旁白:使用int ch1 来区分fgets().

的257 个不同的return 值

避免裸幻数

与其到处乱扔代码 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);
}