【问题标题】:How to compare two files and show all the differences in C?如何比较两个文件并显示 C 中的所有差异?
【发布时间】:2015-05-20 19:17:35
【问题描述】:

我目前正在尝试制作一个程序来比较 2 个文件并显示所有差异。

我遇到的问题是:

  • 结果的第一行没有显示第一个字符。

  • 差异没有正确的结果。

我有两个输入文件。

文件.txt

AAA
BBB
CCC
DDD
EEE

file2.txt

AAA
111
BBB
222
333
CCC
DDD
EEE
444

我得到的输出(第一行被窃听)是:

11
BBB
222
333
CCC

我希望得到的输出(没有第一行错误)必须是:

111
222
333
444

这是我目前的代码:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>

int compare(char *fname1, char *fname2)
{
    FILE *fp1 = fopen(fname1, "r"); 
    FILE *fp2 = fopen(fname2, "r");
    int ch1, ch2;

    if (fp1 == NULL) 
    {
        printf("Can't open %s", fname1);
        exit(1);
    } 
    else if (fp2 == NULL)
    {
        printf("Can't open %s", fname2);
        exit(1);
    } 
    else
    {
        ch1 = getc(fp1);    
        ch2 = getc(fp2);

        while ((ch1 != EOF) && (ch2 != EOF) && (ch1 == ch2)) 
        {
            ch1 = getc(fp1);
            ch2 = getc(fp2);
        }

        if (ch1 == ch2)
        {
            printf("Same. \n");
        }
        else if (ch1 != ch2)
        {
            printf("Different strings:\n");

            while(!feof(fp1) && !feof(fp2))
            {
                fgets(fname1, ch1, fp1);
                fgets(fname2, ch2, fp2);

                if(strcmp(fname1, fname2) != 0)
                {
                    printf("%s", fname2);
                }
            }
        }
    }

    fclose(fp1);
    fclose(fp2);
    return 0;
}

以及主要功能:

int main(int argc, char *argv[])
{
    if (argc == 3){
        compare(argv[1], argv[2]);
    }else{
        printf("Usage: ./what file.txt file2.txt \n");
    }
    return 0;
}

比较 file.txt 和 file2.txt 或 file2.txt 和 file.txt 应该得到相同的结果。

【问题讨论】:

  • 至于第一个字符-您首先要逐个字符地读取文件并进行比较。如果字符不相同,那么您正在读取字符串。但是字符串的第一个字符已经被读取了。这就是你不明白的原因。
  • 为什么不用linux diff
  • "显示所有差异" - 所以,如果您在文件 A 和 B 中有 10 行,然后在文件 B 中,您在索引 5 处插入一行,您是否考虑所有行之后并包括 5是不同的,还是只有那一行?
  • 我会将文件逐行读取到字符串数组中并导航它们。从文件 I/O 中抽象出来,这很麻烦且与算法无关。 (不要误会我的意思——我知道这是作业的一部分。但请尝试将 I/O 与数据处理分开。以后如果您拥有可以轻松组合的模块化块,您会很感激的。)跨度>
  • @szczurcio 仅此一行。

标签: c file compare diff


【解决方案1】:

在第一个循环中,getc() 正在消化您丢失的第一个字符。要解决此问题,请尝试仅使用第二个 while() 或在开始下一个 while() 循环之前返回一个字符

【讨论】:

  • ungetc() 是另一种选择。
【解决方案2】:

您对fgets() 的两次调用都是错误的。根据fgets() documentation

char * fgets(char * str, int num, FILE * stream);

str:指向复制读取字符串的字符数组的指针。

num:要复制到 str 中的最大字符数(包括 终止空字符)。

stream:指向 FILE 对象的指针 标识输入流。 stdin 可以用作读取的参数 标准输入。

尝试写入程序的argv[] 可能不会有好的结果。至少你会想做这样的事情:

char string1[100];
char string2[100];

fgets(string1, 99, fp1);
fgets(string2, 99, fp2);

还有be aware 这样使用feof() 可能是错误的做法。

至于您的比较问题...尝试进行文件比较并检查添加/删除的字符串并不是一个简单的问题。您可以从this question 开始了解一些背景知识。

【讨论】:

  • 为什么在fgets 调用中指定缓冲区长度比实际值小一?如上述文档中所述,该计数包括空终止符。另外,不要使用硬编码的缓冲区大小,如果更改大小很容易导致错误,请使用sizeof
  • 关于-1 缓冲区大小的好点,我没有意识到这一点。我同意你的另一点,但不想让答案太长/太复杂。
猜你喜欢
  • 2015-08-10
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-12-11
  • 1970-01-01
  • 2017-06-06
相关资源
最近更新 更多