2013-03-16 68 views
-3

正如标题所示,我需要比较2个文件。如果一行代码出现,这两个文件之间的内容不一样,请打印该行(来自两个文件)。代码提供了一个don'发送error.I似乎无法找到我的代码中的错误。比较c中的两个文件

#include <stdio.h> 
#include <string.h> 
#define MAX 1000 

int main(int argc, char *argv[]) { 
    char c1, c2; 
    char s1[MAX], s2[MAX]; 
    char *p1; 
    char *p2; 
    FILE *fp1; 
    FILE *fp2; 
    fp1 = fopen(argv[1], "r"); 
    fp2 = fopen(argv[2], "r"); 
    p1 = s1; 
    p2 = s2; 
    if (argc != 3) { 
     printf("Wrong use of program \n "); 
     return -1; 
    } 
    if (fp1 == NULL || fp2 == NULL) { 
     printf("One or both of the files can't be used \n "); 
     return -1; 
    } 
    while ((c1 = getc(fp1)) != EOF || (c2 = getc(fp2)) != EOF) { 
     *p1 = c1; 
     *p2 = c2; 
     p1++; 
     p2++; 

     for (c1 = getc(fp1); c1 != '\n'; p1++) { 
      *p1 = c1; 
     } 
     *p1 = '\0'; 

     for (c2 = getc(fp2); c2 != '\n'; p2++) { 
      *p2 = c2; 
     } 
     *p2 = '\0'; 
     if (!(strcmp(s1, s2))) { 
      printf("%s \n ", s1); 
      printf("%s \n ", s2); 
      return 0; 
     } 
    } 
    return 0; 
} 
+4

A *不发送错误*? – Tchoupi 2013-03-16 22:07:41

+0

编译所有警告和调试信息(例如Linux上的'gcc -Wall -g')和*学习如何使用调试器*(例如Linux上的'gdb')。 – 2013-03-16 22:08:17

+1

对于初学者来说,我会考虑将字符串分配给's1'和's2'的位置。 – Joe 2013-03-16 22:10:24

回答

1

在你有循环的初始化部分getc两个for循环,就会把一个字符c1c2一次,然后做循环,直到你超越的s1s2通过限制你的指针p1p2。由于c1 != '\n'从来没有满足,除非你的第一个字符是'\ n'它可能会引发分段错误错误。

while上,至少在gcc和我的系统上,它做了懒惰的评估(编辑:不懒惰但短路评估,请参阅注释),如果其他部分为真,则不执行该部分。

您也不会在每行后重置p1p2

strcmp如果两个字符串相等,则返回0;在C中,0为假且非零为真,因此您在第一次匹配时退出。

这是一个几乎没有功能的代码版本,你仍然需要处理它,并考虑到一个文件比另一个文件短的情况,文件中的一行大于1000个字符(因为它是正确的现在它会溢出s1s2)等

#include <stdio.h> 
#include <string.h> 
#define MAX 1000 

int main(int argc, char *argv[]) { 
    char c1, c2; 
    char s1[MAX], s2[MAX]; 
    char *p1; 
    char *p2; 
    FILE *fp1; 
    FILE *fp2; 
    p1 = s1; 
    p2 = s2; 
    if (argc != 3) { 
    printf("Wrong use of program \n "); 
    return -1; 
    } 
    fp1 = fopen(argv[1], "r"); 
    fp2 = fopen(argv[2], "r"); 
    if (fp1 == NULL || fp2 == NULL) { 
    printf("One or both of the files can't be used \n "); 
    return -1; 
    } 
    c1 = getc(fp1); 
    c2 = getc(fp2); 
    while ((c1 != EOF) && (c2 != EOF)) { 
    for (; c1 != '\n'; p1++) { 
     *p1 = c1; 
     c1 = getc(fp1); 
    } 
    *p1 = '\0'; 

    for (; c2 != '\n'; p2++) { 
     *p2 = c2; 
     c2 = getc(fp2); 
    } 
    *p2 = '\0'; 
    if ((strcmp(s1, s2)) != 0) { 
     printf("%s\n", s1); 
     printf("%s\n", s2); 
     return 0; 
    } 
    c1 = getc(fp1); 
    c2 = getc(fp2); 
    p1 = s1; 
    p2 = s2; 
    } 
    if (c1 != EOF || c2 != EOF) 
    printf("One of the files ended prematurely\n"); 
    return 0; 
} 
+0

谢谢你,我所需要的。我知道,如果一条线比1000大,它会导致一个错误,我只是想用更少的线测试代码。 – Lind 2013-03-17 09:42:40

+1

澄清:C和C++语言定义了当x不为零时执行if(x || y)时会发生什么 - 具体地说,y没有被评估(因为x是'true',所以不需要这样做)。这不是“懒惰的评估”,也不是“至少在gcc和我的系统上”。它在语言中定义;总是如此。 – jarmod 2013-03-23 01:41:32

+0

@jarmod感谢您的澄清。我的不好,我在那里得到了错误的概念,这就是所谓的“短路评估”,不是吗? – 2013-03-23 15:54:08

1

如果这两个文件是文本文件的话,说实话,我会从头开始使用与fgets(),而不是GETC一个更简单的程序()和逐行比较使用strcmp()而不是逐个字符。代码中的错误太多了 - 如果您丢弃了所拥有的内容,并且使用更简单的解决方案重新开始,您将更快地完成任务。

顺便说一下,如果两个字符串相同,strcmp返回零,如果它们不同,则返回非零。