質問: 基礎的な質問でごめんなさい textin.txt ファイルの空白、改行をすべて取り除いて、textout.txtファイルに出力したいです ``` #include #include #include int main(){ FILE *fp,*fq; char str[100]; int i; fp=fopen("textin.txt","r"); if(fp==NULL){ printf("File open error1\n"); return 1; }//File読み込みに失敗した場合 fq=fopen("textout.txt","w"); if(fq==NULL){ printf("File open error2\n"); return 1; }//File読み込みに失敗した場合 while(fscanf(fp,"%s",str)!=NULL){ for(i=0;i<=strlen(str)-1;i++){ fputc(str[i],fq); } } fclose(fp); fclose(fq); return 0; } ``` このコードだとコンパイル時にwhile文の部分で「整数とポインタを比較しています」というエラーが出ます 疑問点は2つです 1なぜこのようなエラーがでるのか (fscanfがint型としてNULLがポインタ型と見られてしまうのはなぜか) 2エラーが出ない書き方はどのようなものか ご教授お願いしますm(__)m
回答: cateyeさんの回答が正鵠を射ていますが、補足。 fscanf関数は、scanf/printf系統に分類され、正常に入力された項目数(読み込みエラー時はEOF)を返します。 fgets関数は、gets/puts系統に分類され、入力された内容へのポインタ(エラー時はNULL)を返します。 要するに、似た目的で利用される関数ではあるが、返り値の仕様が違うわけです。昔からの伝統で規格化されたので、こういうもの、と割り切ってもらうしかありません。 本問では、条件式を`while(fscanf(fp,"%s",str)>0)`とすれば、正しく動作します。 以下蛇足:本問とは直接関係がないので、余裕があれば読んでください。 このプログラムには、あと2ヶ所、問題があります。 1つ目は、書き込み用ファイルが開けない場合の処理です。読み込み用ファイルが開いたままに、なりませんか? 2つ目は、長い単語入力があった場合です。もし101桁の数字が入力されたら、バッファオーバーフローが発生します。バッファオーバーフローは、時に深刻なセキュリティホールになります。修正方法ですが、`while(fscanf(fp,"%99s",str)>0)`と、fscanf関数の引数で桁数を指定すれば、この問題は回避されます。