2016-04-08 13 views
0

プログラム:のgetc関数の農産物セグメンテーション違反

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

char *f_gets(char *s, int n, FILE *iop) 
{ 
    int c=0; 
    char *cs; 
    cs = s; 

    while (--n > 0 && (c = getc(iop)) != EOF) 
    { 
     if ((*cs++ = c) == '\n') 
      break; 
    } 
    *cs = '\0'; 
    return (c == EOF && cs == s) ? NULL : s; 
} 


main(int argc, char *argv[]) 
{ 
    FILE *fp1,*fp2; 
    char s2[100],s1[100]; 
    if (argc <= 2) 
     printf("2 argument needed \n"); 
    else 
     if((fp1=fopen(argv[1],"r"))== NULL && (fp2=fopen(argv[2],"r"))==NULL) 
      printf("cat: can't open The file\n"); 
     else 
     { 
      while(1) 
      { 
       f_gets(s1,100,fp1); // 1st iteration 
       f_gets(s2,100,fp2); // 2nd iteration 
       if(!strcmp(s1,s2)) 
        printf("%s %s",s1,s2); 
      } 
      fclose(fp1); 
      fclose(fp2); 
     } 
} 

が出力:上記のプログラムで

$ ./a.out a b 
Segmentation fault (core dumped) 
$ 

我々は2回目f_getsを呼び出すときに、セグメンテーション違反が発生します。私が2度プログラムをチェックしても、 の問題を見つけるのは難しいです。誰が原因で問題が発生するのか説明しています。

答えて

8

2番目のファイルは、電話をかけた時点では開いていません。

問題は、あなたが短絡してパスからfopenを呼び出しているということです。

if((fp1=fopen(argv[1],"r"))== NULL && (fp2=fopen(argv[2],"r"))==NULL) 

ので、あなたのコード内でのミスのfp1が細かい開いたときに、fp2は常に閉じたままになります。これは、(fp1=fopen(argv[1],"r"))== NULL0と評価され、(fp2=fopen(argv[2],"r"))==NULLが決して呼び出されないことを保証するためです。

&&||に置き換えて修正できますが、一度に1ファイルずつ開くほうがよいでしょう。

2
if((fp1=fopen(argv[1],"r"))== NULL && (fp2=fopen(argv[2],"r"))==NULL) 

は、「プログラムがfp1とfp2の両方を開けなかった場合」を意味します。代わりに||を使用してこれを解決できます。しかし、長い文章や複雑な文章を書いてはいけません。バグを書く可能性が増します。代わりに

は、次の操作を行います。

fp1=fopen(argv[1],"r"); 
if(fp1 == NULL) 
{ 
    // error handling 
} 

fp2=fopen(argv[2],"r"); 
if(fp2 == NULL) 
{ 
    fclose(fp1); 
    // error handling 
} 

そしてボーナスとして

は:私たちは何かに読み取り可能なプログラムを再度書いたという理由だけで、我々は今、第二のバグを見つけました。プログラムがfp1をオープンしたがfp2をオープンできなかった場合は、fp1を決してクローズしてから中止した。

関連する問題