質問: int main(void){ FILE *fp_r,*fp_w; int eng,math,num,sum; if((fp_r=fopen("kison.data","r"))==NULL){ printf("ファイルを開けません\n"); } else if((fp_w=fopen("betu.data","w"))==NULL){ }else{ while( !feof(fp_r)){ fscanf(fp_r,"%d%d%d",&num,&eng,&math); sum=eng+math; if(sum>=120){ fprintf(fp_w,"%d %d %d %d 合格 \n",num,eng,math,sum); }else{ fprintf(fp_w,"%d %d %d %d 不合格 \n",num,eng,math,sum); } } fclose(fp_w); fclose(fp_r); } return 0; } ### 試したこと 1つ目のif文でNULLが出た時にプログラムが終了していないことに気づいて、betu.dataを開くif文をelse if文に書き換えたとたんにこの現象が現れました。 なので、タップミスか何かでループ本体を触ってしまったのかと思い、書き換える前に戻してみたりもしましたが、一向に直りませんでした。 自分でもどうしてこうなるのか本当にわからなくて、行き詰っています。 ### 補足情報(FW/ツールのバージョンなど) ここにより詳細な情報を記載してください。
回答: feof の使い方を間違っているからです。 feof はこれより前の入力関数が、 ファイルの終わりに達してエラーになったことを示すものです。 feof(fp_r) が 0、すなわち !feof(fp_r) が 1だからといって 次の fscanf がエラーにならないことを保証するものではありません。 fscanf で 3行目のデータまで読めても、まだ feof は 0 のままです。 4回目の fscanf は失敗するのですが、それはチェックしていないので 3回目のデータをそのまま出力しています。 修正方法は ``` while (fscanf(fp_r, "%d%d%d", &num, &eng, &math) == 3) { ``` または、 ``` while (1) { fscanf(fp_r, "%d%d%d", &num, &eng, &math); if (feof(fp_r)) break; ``` feof の間違った使い方の例を挙げます。 ``` int c; while (!feof(fp)) { c = fgetc(fp); putchar(c); } ``` 1文字余計に出力されてしまいます。 たいていの場合最後の文字は改行文字なので気が付かないことが多い。 ``` char buf[1024]; while (!feof(fp)) { fgets(buf, sizeof buf, fp); fputs(buf, stdout); } ``` 最後の行が 2つ出てしまいます。