-1

Linux のマニュアルでは、このfflush機能を使用しないことを推奨しています。

while( getchar() != '\n'それで、が と同じ役割を果たすことがわかりましたfflush(stdin)

例えば)

私の試用コード:

#include <stdio.h>

void main(void)
{
    char input[100] = {};
    printf("abcd");
    while(1);
}

上記のコードを Linux (Ubuntu) で実行すると、結果は何もありません。は文字列に含まれていないため\nです。stdoutしたがって、バッファを空にしてそれらを出力する必要があります。

奇妙な現象は、どちらかgetc(stdout)またはを使用すると、結果がうまく印刷されることgetc(stdin)です。

#include <stdio.h>

void main(void)
{
    char input[100] = {};
    printf("abcd");
    getc(stdout); // or getc(stdin); both working well.
    while(1);
}

なぜ両方がうまくいっているのかわかりません。私は、キーボード バッファーとモニター バッファーgetc(stdout)を考えているので、うまく動作するはずだと思っていました。stdinstdout

4

2 に答える 2

2

fflush(3)のドキュメントを注意深く読んでください(入力ストリームの場合、これはシーク可能なファイルにのみ効果があり、端末の場合のstdinには効果がありません)。私の知る限り、fflush(stdin)未定義の動作(標準while( getchar() != '\n'入力が端末の場合)であり、確かに;と同じことはしません 。fflushいくつかの出力 FILE*ハンドルまたはで呼び出す必要がありますNULL

最初の例は、ビジー待機ループの前にafflush(NULL);または呼び出しを追加すると、期待どおりに機能します (実際には、少なくともプロセッサの加熱を避けるために、そのループ内でsleep(3)を呼び出す必要があります)。fflush(stdout);while(1);

stdinは (Linux では) tty(4)、またはファイルまたはpipe(7) (たとえば、シェルのリダイレクトまたはパイプラインを使用) などになる可能性があることに注意してください。

端末、つまり tty は、主に歴史的な理由から、非常に複雑なものです。ttyのわかりやすいページを読んでください。多くの場合、ダブルバッファリングが発生します。カーネルはライン ディシプリンを介して tty をバッファリングし、C 標準ライブラリstdinをバッファリングします。setvbuf(3)を参照してください。もちろん、tty はキーボードではありません (ただし、その上にいくつかの抽象化があります)。おそらく、Linux デスクトップでは、物理キーボードはX11サーバーによってのみ読み取られます。

端末からのインタラクティブな入力が必要な場合は、 ncursesreadlineなどのライブラリの使用を検討してください。

高度な Linux プログラミングを読む

そして、2番目のケースの動作は、一部のC標準ライブラリがstdinから読み取る前にstdoutを暗黙的にフラッシュしているという事実によって説明できますが、知る限り、これは保証されておらず、必要に応じて(特に読みやすさの理由で)明示的に呼び出す必要があります! fflush

getc(3)のドキュメントを読んでください。失敗する可能性があります (おそらく で失敗するでしょうstdout)。

于 2015-11-30T05:36:25.477 に答える
-1

setbuf(stdout, NULL); を使用できます。fflush(stdin) と同じ効果を得るための関数呼び出し。

于 2015-11-30T05:36:03.873 に答える