25

7.9.13/7次のような状態のセクションc99:

プログラムの起動時に、3 つのテキスト ストリームが事前定義されており、明示的に開く必要はありません。標準入力 (従来の入力を読み取るため)、標準出力 (従来の出力を書き込むため)、および標準エラー (診断出力を書き込むため) です。

最初に開いたとき、標準エラー ストリームは完全にバッファリングされていません。標準入力および標準出力ストリームは、ストリームが対話型デバイスを参照していないと判断できる場合にのみ、完全にバッファリングされます。

それは理にかなっています。標準出力をファイルにプッシュする場合は、効率のために完全にバッファリングする必要があります。

しかし、デバイスが非対話型 (つまり、端末への通常の出力) であると判断できない場合に、出力がライン バッファーか非バッファーかについて、標準には言及されていません。

私が尋ねる理由は、2 つのステートメントの間に を挿入する必要があるというの回答へのコメントでした。fflush(stdout);

printf ("Enter number> ");
// fflush (stdout); needed ?
if (fgets (buff, sizeof(buff), stdin) == NULL) { ... }

printf改行で終了していなかったからです。誰でもこれをクリアできますか?

4

1 に答える 1

35

C99 標準では、3 つの標準ストリームがバッファリングされていないか行バッファリングされているかは指定されていません。これは実装次第です。私が知っているすべての UNIX 実装では、行がバッファリングされていstdinます。Linux ではstdout、インライン バッファありおよびstderrバッファなし。

私の知る限り、POSIX は追加の制限を課していません。POSIX のfflushページでは、例のセクションに次のように記載されています。

[...] fflush()関数が使用されるのは、標準出力が通常バッファリングされ、プロンプトが出力または端末にすぐに表示されない場合があるためです。

したがって、あなたが追加した発言fflush(stdout);は正しいです。


stdout別の方法として、バッファなしにすることもできます。

setbuf(stdout, NULL);
/* or */
setvbuf(stdout, NULL, _IONBF, 0);

stdoutしかし、R. が指摘しているように、これは 1 回しか実行できず、書き込みまたは他の操作を実行する前でなければなりません。(C99 7.19.5.5 2)


同じことについての最近のスレッドを読みましたcomp.lang.c。発言の1つ:

Unix の慣例では、stdinstdoutは端末に関連付けられている場合はライン バッファリングされ、それ以外の場合は完全にバッファリングされます (ブロック バッファリングとも呼ばれます)。stderrは常にバッファリングされません。

于 2010-09-19T17:52:34.637 に答える