比较2个文件

时间:2016-12-11 22:59:57

标签: c file

我有一个问题,我需要制作一个比较两个文件的程序。 如果在第一个文件中我有:

Milk
Sugar
Eggs

在第二个文件中我有

Vanilla
Soda
Sugar

我想显示两个文件中出现的行。

我没有很多c经验,但我尝试了一些东西。 但我的问题是,如果他们不在同一条线上,我将如何显示Sugar作为输出?

#include <stdio.h>
#include <stdlib.h>
#include<string.h>
#define MAX 100

void equal (char*lineone,char*linetwo){
    if(strcmp(lineone,linetwo)==0){
        printf("%s",lineone);
    }
}
int main(){
    FILE *fp1,*fp2;
    fp1=fopen("D:/aici/file1.txt","r");
    fp2=fopen("D:/aici/file2.txt","r");
    char buff[MAX],buff1[MAX];
    int i=0;
    while((fgets(buff,MAX,fp1)!=NULL)&&(fgets(buff1,MAX,fp2))!=NULL){
            //i++;
            equal(buff,buff1);
    }
}

2 个答案:

答案 0 :(得分:1)

你应该做什么(出于性能原因)是将所有单词保存到两个缓冲区中然后进行比较。 但是,您也可以通过稍微改变实现来实现, 只需要将循环分离到一个主循环和一个内循环,这样你就可以得到这样的效果:对于文件1中的每个单词,它将比较文件2中的所有单词,再次,比较时非常慢的方法,只需先保存所有单词然后才相互比较。

void equal (char*lione,char*linetwo){
    if(strcmp(lione,linetwo)==0){
        printf("%s",lineone);
    }
}
int main(){
    FILE *fp1,*fp2;
    fp1=fopen("D:/aici/file1.txt","r");
    fp2=fopen("D:/aici/file2.txt","r");
    char buff[MAX],buff1[MAX];
    int i=0;
    while(fgets(buff,MAX,fp1)!=NULL) {
          while(fgets(buff1,MAX,fp2))!=NULL){
           //i++;
            equal(buff,buff1);
          }

         rewind(fp2);
     }

}

答案 1 :(得分:0)

继续评论,您是否继续使用fgets(推荐),或者您认识到您也可以使用fscanf而不必担心从每个字词中移除'\n',需要验证程序的每一步。虽然fscanf一开始可能看起来更容易,但您可能需要了解man fscanf并确定如何控制每个文件流中将保留未读的'\n'

以下是一个简短的示例,继续fgets,展示了如何测试和删除每个尾随的'\n'阅读并包含在buff中的fgets fgets 1}}。 (以及每个步骤的合理验证)。 (注意:我假设由于你的输入是一个单词,256-char缓冲区就足够了 - 假设 unabridged 字典中最长的单词是28个字符,但你也可以验证是否#include <stdio.h> #include <string.h> #define MAXC 256 int main (int argc, char **argv) { if (argc < 3) { /* validate 2 arguments given */ fprintf (stderr, "error: insufficient input.\n" "usage: %s file1 file2\n", argv[0]); return 1; } char buf1[MAXC] = "", /* declare buf1 */ buf2[MAXC] = ""; /* declare buf2 */ FILE *f1 = fopen (argv[1], "r"), /* open file 1 */ *f2 = fopen (argv[2], "r"); /* open file 2 */ if (!f1) { /* validate file 1 open for reading */ fprintf (stderr, "file open failed '%s'\n", argv[1]); return 1; } if (!f2) { /* validate file 2 open for reading */ fprintf (stderr, "file open failed '%s'\n", argv[2]); return 1; } while (fgets (buf1, MAXC, f1)) { /* read each word in file 1 */ size_t len1 = strlen (buf1); /* get length */ if (len1 && buf1[len1 - 1] == '\n') buf1[--len1] = 0; /* overwrite '\n' with nul-byte */ while (fgets (buf2, MAXC, f2)) { /* read each in file 2 */ size_t len2 = strlen (buf2); if (len2 && buf2[len2 - 1] == '\n') buf2[--len2] = 0; /* overwrite '\n' with nul-byte */ if (len1 != len2) /* if lengths differ, not equal */ continue; /* get next word from file 2 */ if (strcmp (buf1, buf2) == 0) /* compare strings */ printf ("%s\n", buf1); /* print if equal */ } rewind (f2); /* rewind f2, clear EOF */ } fclose (f1); /* close f1 */ fclose (f2); /* close f2 */ return 0; } 已完整阅读每一行,或者其他字符是否仍然未读)

以下代码要求将每个文件的文件名作为程序的前两个参数。

if (len1 != len2)

(注意:长度检查strcmp只是一个效率检查,阻止调用strcmp,除非单词的长度相等。对长度(你已经拥有)的简单比较要少得多比每次$ cat dat/f1cmp.txt Milk Sugar Eggs $ cat dat/f2cmp.txt Vanilla Soda Sugar 的完整函数调用贵(注意,这是一个非常小的节省,如果你愿意,你可以删除))

输入文件(故意没有POSIX-eol)

数据文件是在没有POSIX行尾的情况下有意创建的,以证明如果你正确处理新行删除,它对结果没有任何影响。

$ ./bin/fgets_cmp_words dat/f1cmp.txt dat/f2cmp.txt
Sugar

示例使用/输出

buf1

仔细研究并完成验证。如果您有任何其他问题,请与我们联系。

显示单词不同的地方

要显示单词的不同之处,您只需要修改内部循环。您可以通过循环buf2strcmp != 0中的字符进行简单比较,并在找到第一个差异时停止。您可以继续上述(1)长度不同的两种情况; (2)返回strcmp,或者你可以在 while (fgets (buf2, MAXC, f2)) { /* read each in file 2 */ size_t len2 = strlen (buf2); int i = 0; if (len2 && buf2[len2 - 1] == '\n') buf2[--len2] = 0; /* overwrite '\n' with nul-byte */ if (len1 != len2) { /* if lengths differ, not equal */ /* locate & output difference */ for (i = 0; buf1[i] == buf2[i]; i++) {} printf ("%s & %s differ at char %d (%c != %c)\n", buf1, buf2, i, buf1[i], buf2[i]); continue; /* get next word from file 2 */ } if (strcmp (buf1, buf2) == 0) /* compare strings */ printf ("%s\n", buf1); /* print if equal */ else { /* locate & output difference */ for (i = 0; buf1[i] == buf2[i]; i++) {} printf ("%s & %s differ at char %d (%c != %c)\n", buf1, buf2, i, buf1[i], buf2[i]); } } 的非归零后进行单一测试。

上面对内循环的修改如下所示。我不知道你要找的是什么输出格式,所以我只输出不同的单词并显示单词开始不同的字符(从零开始索引):

$ ./bin/fgets_cmp_wrds dat/f1cmp.txt dat/f2cmp.txt
Milk & Vanilla differ at char 0 (M != V)
Milk & Soda differ at char 0 (M != S)
Milk & Sugar differ at char 0 (M != S)
Sugar & Vanilla differ at char 0 (S != V)
Sugar & Soda differ at char 1 (u != o)
Sugar
Eggs & Vanilla differ at char 0 (E != V)
Eggs & Soda differ at char 0 (E != S)
Eggs & Sugar differ at char 0 (E != S)

示例使用/输出

wizard

仔细看看,如果您有其他问题,请告诉我。