11

Linux System Programmingで、私は次のようなものを読みました:

fgetcファイルまたはエラーの最後にor unsigned charへのキャストとして読み取られた文字を返します。使用する一般的なエラーは次のとおりです。intEOFfgetc

char c;
if ((c = fgetc()) != EOF) {...}

このコードの正しいバージョンは次のとおりです。

int c;
if ((c = fgetc()) != EOF) { printf("%c", (char)c); ... }

では、なぜcharと比較する前に戻り値をキャストできないのEOFでしょうか? EOFと正確に比較する必要があるのはなぜintですか? としてEOF定義されているよう-1に、通常は にキャストされcharませんか?
そうでないプラットフォーム/コンパイラはありますか?

4

2 に答える 2

11

EOF戻り値は である可能性があり、EOFvalue はシステムに依存し、有効な文字コードと等しくないため、戻り値を char にキャストすることはできません。リンク

通常はそうです-1が、それを想定しないでください。

c-faq-siteからのこの素晴らしい回答を確認してください:

上記のフラグメントのように、getchar の戻り値が char に割り当てられている場合、2 つの失敗モードが考えられます。

  1. char 型が符号付きで、EOF が (通常どおり) -1 として定義されている場合、10 進値 255 (C では '\377' または '\xff') の文字は符号拡張され、次と等しいと比較されます。 EOF、入力を途中で終了します。(8ビットの文字を想定)。

  2. char 型が unsigned の場合、実際の EOF 値は切り捨てられ (上位ビットが破棄され、おそらく 255 または 0xff になる)、EOF として認識されず、事実上無限の入力になります。

それが役に立てば幸い!

編集: (この回答に @FatalError コメントを追加しました。これは c-faq サイトで説明されていますが、これは私にはより明確に見えます)

「charにキャストすると、EOFは有効な文字と同じ値を取るため、その文字と区別できなくなります。それだけで、結果をcharにしない十分な理由になるはずです」@FatalErrorコメント。

于 2012-06-15T19:49:36.917 に答える
4

charEOF と比較する前に値を a に代入する場合、次の 2 つの可能性があります。

  • char符号付きの値です。その場合、EOF と誤って解釈される正当な文字 (多くの場合、ÿ、分音符付きの小文字 Y、U+00FF) があります。
  • char符号なしの値です。その場合、EOF は 0xFF に変換さintれ、正の値として昇格されます。これは、負の値である EOF と決して等しくなりません。

いずれにせよ、プログラムは時々誤動作します。

代入は正しく行われたが、代入された値が比較に使用されなかったというコンパイラのバグの可能性があります (または、より正確には、以前はそうでした)。これにより、正常に動作していない場合でもコードが正常に動作しているように見えます。幸いなことに、これが最新のコンパイラで見られる問題になる可能性はほとんどありません。

于 2012-06-15T20:13:06.493 に答える