2013-03-16 109 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返回零,如果它們不同,則返回非零。