4

私はこのコードを持っています

while(1){
    printf("hello world !\n");
    fgetc(stdin);
}

これが実行され、次のような文字を入力すると:

hello world !
a

次のループで fgetc(stdin) を無視し、入力を待たずに hello world を 2 回出力します。

hello world !
a
hello world !
hello world !
a
hello world !
hello world !
a
hello world !
hello world !
a
hello world !
hello world !

fgetc(stdin) の前または後に fflush(stdin) を配置しようとしましたが、それでも同じ動作が生成されます。何が間違っていますか?

4

4 に答える 4

8

これは、実際には 'a' と改行の 2 つの文字を入力するためです。また、端末は通常行バッファリングされているため、改行を入力すると、プログラムは入力のみを認識します。長いテキスト行を入力することも有益です。

この動作を変更したい場合は、2 つのオプションがあります。行全体 (つまり、改行またはファイルの終わりまでのすべての文字) を読み取るか、端末を非標準モードに切り替えることです。後者は、テキスト エディターのようなインタラクティブな端末アプリケーションで作業している場合に適しています。詳細については、 termios のマンページを参照してください。つまり、MIN および TIME オプションを 0 に設定して、データが利用可能になるとすぐに端末からの読み取りを返すようにする必要があります。このパスをたどる場合は、信号の受信によるものも含め、終了するときにターミナルを元に戻すようにしてください。

fflush()入力ではなく、出力に影響します。

于 2012-08-21T22:21:00.657 に答える
5

端末はライン バッファリングされる傾向があります。つまり、ストリーム コンテンツはライン単位でアクセスできます。

そのため、fgetcSTDIN から読み取りを開始すると、その行を終了する改行文字を含む行全体が読み取られます。それはあなたが読んでいる 2 番目の文字です。

に関してはfflush、それは入力バッファではなく、出力バッファをフラッシュするためのものです。

したがって、ここでやりたいことは、入力バッファーが空になるまで読み取ることによって入力バッファーをパージするか、改行文字を明示的に無視することです。

于 2012-08-21T22:24:25.823 に答える
2

a\n(改行)の 2 つの文字があります。ループの読み取りは を読み取り、aループして「hello world !」を出力します。次に、\n「hello world !」を認識してループし、出力します。aターミナルで+と入力\nすると、2 つの文字が stdin バッファーに格納されます。fgetc(stdin);使用可能な char がある場合は stdin バッファーから読み取ります。それ以外の場合は、char がバッファーに追加されるまで待機します。

端末は行バッファリングされているため (つまり、改行に到達するまでコンテンツをプログラムに送信しない)、いくつかのオプションがあります。

  • 行全体をバッファに読み込みますが、最初の文字のみを取ります
  • 改行を無視する
  • ラインバッファリングをオフにする

行バッファリングをオフにするには、http://c-faq.com/osdep/cbreak.htmlhttp://www.flipcode.com/archives/_kbhit_for_Linux.shtmlhttp://ubuntuforums.org/showthread を見てください。 php?t=225713 (ただし、ここのコードはテストしていません)。

于 2012-08-21T22:21:17.190 に答える
1

そこには 2 人のキャラクターがいて'a''\n'. fgetc は 1 文字しか読み取らないため、これが問題です。これはドキュメントです。

のみを入力すると、Enter キーのみ'\n'を押すと、期待どおりの動作が得られます。

それが役に立てば幸い!

于 2012-08-21T22:23:49.590 に答える