- ベストアンサー
ファイル入出力について
次のようなプログラムを作りました。 コマンドラインから二つのファイルの名前を読み取り、最初の引数のファイルを2番目の引数のファイルにコピーするプログラムです。 質問は下のプログラムのコメント /*この行が質問です*/ の所です。 //ファイルをコピーする の部分の始めに while(!feof(from)) という条件を書いているため、/*この行が質問です*/ の行は不要であると思いましたが、実際にこの一行をのぞいてコンパイルして実行したところ、日本語が文字化けしてコピーされてしまいました。その後、この行を追加してコンパイルして実行すると文字化けもなく実行できました。 なぜこの行が必要なのでしょうか。 よろしくお願いします。 //ファイルコピー #include<stdio.h> #include<stdlib.h> int main(int argc, char *argv[]) { FILE *from, *to; char ch; //引数の数の確認 if (argc != 3) { printf("引数の数が違います"); exit(1); } //コピー元ファイルを開く if ((from = fopen(argv[1],"r")) == NULL ) { printf("コピー元ファイルオープンエラー"); exit(1); } //コピー先ファイルを開く if ((to = fopen(argv[2],"w") )== NULL ) { printf("コピー先ファイルオープンエラー"); exit(1); } //ファイルをコピーする while (!feof(from)) { ch = fgetc(from); if(ferror(from)) { printf("コピー元ファイル読み込みエラー"); exit(1); } if (!feof(from)) /*この行が質問です*/ fputc(ch,to); if (ferror(to)) { printf("コピー先ファイル書き込みエラー"); exit(1); } } if (fclose(from) == EOF) { printf("コピー元ファイルクローズエラー"); exit(1); } if (fclose(to) == EOF) { printf("コピー先ファイルクローズエラー"); exit(1); } return 0; }
- みんなの回答 (2)
- 専門家の回答
質問者が選んだベストアンサー
単純には「ファイルが終わったかどうかは読んでみないとわからない」ってことかな. その if 文がないと, 「ファイルの終端」で行った getc が読み込んだ「文字」も出力します. だから feof は意外と使いにくく, while ((ch = getc(from)) != EOF) { ... } というループを組む方が普通.
その他の回答 (1)
- notnot
- ベストアンサー率47% (4900/10358)
#1の方がお書きのように、feof()は読んでからチェックする関数です。 元のプログラムを出来るだけ変えないとすると、 while(ch=fgetc(from), !feof(from)) { でしょうか。これでループ内でのfeofチェックは不要です。 >日本語が文字化けしてコピーされてしまいました。 お書きのようにしても、最後にゴミが1バイト付くだけなので文字化けにはならないはずですが。 あと、#1の方がお書きのように EOF を使った判断にするのであれば、EOFはint型なので、char ch;でなくint ch;と宣言する必要があります。
お礼
feof は読んでからチェックする関数だというところが盲点でした。 やはり何度か試してみましたが文字化けしてしまいます。これはプログラムが原因ではないということですので、ほかの原因をチェックしてみたいと思います。 EOFには整数型を適用しなければならないのですね。細かい注意をありがとうございます。 細かいところまで丁寧な回答をありがとうございました。
お礼
feof は 読み込んでからでないと、終わったかどうか判定できないのですね!! 少し感覚とずれた使い方をするものなのですね。 その点を考えると、おっしゃるとおり while ((ch = getc(from)) != EOF) { ... } というループの方が直感的にもわかりやすく使いやすいです。 親切な回答をありがとうございました。