web-dev-qa-db-ja.com

Cのファイルの終わり(EOF)

現在、Ritchie&Kernighanの著書C Programming Languageを読んでいます。そして、getchar()関数でのEOFの使用についてかなり混乱しています。

最初に、EOFの値が-1であり、getchar()!=EOFの値が0である理由を知りたいと思います。私の質問をご容赦ください。しかし、本当に理解できません。本当に試しましたが、できません。

次に、以下のコードを使用して文字数をカウントできる本の例を実行しようとしましたが、Enterキーを押してもループから抜けることはないようですので、いつEOFに到達するのだろうか?

main(){
   long nc;
   nc = 0;
   while (getchar() != EOF)
       ++nc;
   printf("%ld\n", nc);
}

次に、 CのEOFの問題 で同じ問題を読みました。ほとんどの人は、EOFを使用する代わりに、ターミネータ\ nまたはヌルターミネータ「\ 0」を使用することをお勧めします。

この本の例が別の目的に役立つということですか?

57
newbie

EOFは「ファイルの終わり」を示します。改行(Enterキーを押すと何が起こるか)はfileの終わりではなく、lineの終わりなので、改行はこれを終了しませんループ。

コードは間違っていません[*]、あなたが期待しているようには見えません。入力の最後まで読みますが、行の最後までしか読みたくないようです。

EOFの値は、実際の文字であるgetcharからの戻り値と異なる必要があるため、-1です。したがって、getcharは、任意の文字値を符号なしcharとして返し、intに変換されるため、負ではありません。

端末で入力していて、ファイルの終わりを引き起こしたい場合は、CTRL-D(unixスタイルのシステム)またはCTRL-Z(Windows)を使用します。その後、すべての入力が読み取られた後、getchar()EOFを返すため、getchar() != EOFはfalseになり、ループは終了します。

[*]整数オーバーフローのために入力がLONG_MAX文字を超える場合、未定義の動作になりますが、単純な例ではおそらくそれを許すことができます。

81
Steve Jessop

EOFは-1であるため、それが定義されています。名前は、#includeという標準ライブラリヘッダーによって提供されます。 getchar()によって読み取られる実際のバイトと間違えられないものでなければならないため、-1に等しくします。 getchar()は、正の数(0から255まで)を使用して実際のバイトの値を報告します。したがって、-1で問題なく動作します。

!=演算子は「等しくない」ことを意味します。 0はfalseを表し、それ以外はtrueを表します。そのため、getchar()関数を呼び出し、結果を-1(EOF)と比較します。結果がEOFに等しくなかった場合、等しくないものは等しくないため、結果はtrueになります。結果がEOFに等しかった場合、等しいものは等しくない(等しくない)ため、結果は偽になります。

「ファイルの終わり」に到達すると、getchar()への呼び出しはEOFを返します。 Cに関する限り、「標準入力」(コマンドウィンドウに入力することでプログラムに与えるデータ)は、ファイルのようなものです。もちろん、いつでももっと入力できますので、「完了」と言う明確な方法が必要です。 Windowsシステムでは、これはcontrol-Zです。 Unixシステムでは、これはcontrol-Dです。

本の例は「間違った」ものではありません。 実際に何をしたいかに依存します。 EOFまで読むとは、ユーザーが「完了」と言うまで、すべて読むことを意味し、それ以上読むことはできません。 「\ n」まで読み取ると、入力行を読み取ることを意味します。ユーザーに入力を期待する場合、「\ 0」まで読むのは悪い考えです。コマンドプロンプトでキーボードでこのバイトを生成するのは難しいか不可能であるためです:)

16
Karl Knechtel

それはたくさんの質問です。

  1. EOFが-1である理由:通常、POSIXシステムコールでは-1がエラーで返されるため、「EOFは一種のエラー」だと思います

  2. ブール演算(!=を含む)は、TRUEの場合は1を返し、FALSEの場合は0を返します。したがって、getchar() != EOFはFALSEの場合は0になり、getchar()EOFを返します。

  3. EOFから読み取るときにstdinをエミュレートするには Ctrl+D

7
Drakosha