ファイルを比べて違ってる最初の行を表示

K&R本 演習7-6

二つのファイルを比べて、違っている最初の行を印字するプログラムを書け。

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

char *getline (FILE *fp) {
    char str[100];
    char *p = NULL;
    size_t len = 0;
    size_t lentotal = 0;
    
    while ( fgets(str,sizeof(str),fp) != NULL ) {
        lentotal += len = strlen(str);
        p = (char *)realloc(p,lentotal+1);
        strcpy_s(p+lentotal-len,len+1,str);
        if ( str[len-1] == '\n' ) break;
    }
    
    return p;
}

int main (int argc,char *argv[]) {
    FILE *fp1,*fp2;
    char *p1,*p2;
    char *file1,*file2;
    
    if ( argc < 3 ) {
        fprintf(stderr,"Usage:\n  main file1 file2");
        exit(1);
    }
    
    file1 = *++argv;
    file2 = *++argv;
    
    if ( fopen_s(&fp1,file1,"r") != 0 ) {
        fprintf(stderr,"%s open error",file1);
        exit(2);
    }
    
    if ( fopen_s(&fp2,file2,"r") != 0 ) {
        fclose(fp2);
        fprintf(stderr,"%s open error",file2);
        exit(2);
    }
    
    while ( (p1 = getline(fp1)) != NULL ) {
        p2 = getline(fp2);
        if ( p2 == NULL || strcmp(p1,p2) != 0 ) {
            puts("違う最初の行検出");
            printf("%s: %s\n%s: %s",file1,p1,file2,p2);
            fclose(fp1);
            fclose(fp2);
            exit(0);
        }
    }
    
    if ( (p2 = getline(fp2)) != NULL ) {
        puts("違う最初の行検出");
        printf("%s: \n%s: %s",file1,file2,p2);
    }
    
    fclose(fp1);
    fclose(fp2);
    
    return 0;
}
$ cat test1.txt
aaaaaaaa
bbbbbbbbbbbb
ccccc
dddddddddddddddddd
eeeeeeeeee

$ cat test2.txt
aaaaaaaa
bbbbbbbbbbbb
ccccc
dddddddddddddddddd
oooooooo

$ main test1.txt test2.txt
違う最初の行検出
test1.txt: eeeeeeeeee
test2.txt: oooooooo

できました。

お互いのファイルから一行ずつ読み込んで処理ですね。

一つ目のファイルを全部読み込み終わった後に、二つ目のファイルに行が残ってないかチェックするのがポイントですね。