「スコット・マイヤーズ」の古くて興味深い記事を読んでいるだけです
http://aristeia.com/Papers/C++ReportColumns/novdec95.pdf
基本的には、'\n'
よりもstd::endl
を使用することを好むことです(私はこれに同意し、何年も同じ拡張を使用しています)。
[〜#〜] but [〜#〜]最後のセクションは、2つの理由で全体が無意味になったため、これが彼の本に含まれていなかったことを示していますポイント:
std::cout
はバッファリングされませんでした。ios::unitbuf
の状態は明示的に定義されていません(したがって、実装に依存します)。簡単に調べましたが、1
の明示的な標準参照が真であることがわかりませんでした。 std::cout
は、私がいつも理解していることに反して、バッファリングされていませんか?
はい、バッファリングされています:
C++ 11 27.4.2 [narrow.stream.objects]/3:オブジェクト
cout
は、オブジェクトstdout
に関連付けられたストリームバッファへの出力を制御します
この記事は、C++ 98標準になった1995年のドラフトバージョンに言及しています。それが何か違うことを言っているのかどうかはわかりません。
ポイント2に関しては、unitbuf
とcerr
を除いて、すべてのストリーム(basic_ios
コンストラクターの事後条件で指定)でwcerr
は最初はfalseです。それ以外の場合は明示的に指定します。繰り返しますが、それは参照されている古代のドラフトではかなり異なるかもしれません。
まず、_std::cout
_(または_std::cerr
_)をバッファリング解除する必要はありません。唯一の要件は、_std::cerr
_に_std::basic_ios::unitbuf
_が設定されていることです(各出力関数の最後にフラッシュされるように:_<<
_またはフォーマットされていない出力関数)。一方、std::basic_ios::sync_with_stdio(false)
を呼び出さない限り、C++ストリームへの出力と対応するCストリームへの出力(つまり、_std::cout
_とstdout
)は同じ効果を持つ必要があります。理論的には、これはいくつかの方法で実行できます。stdout
関数は_std::cout
_の関数に転送でき、_std::cout
_出力はstdout
に転送できます。または、内部でいくつかの共通のバッファー実装を共有できます。実際には、事実上すべての実装で_std::cout
_がstdout
に転送されます。
Cは、stderr
が完全にバッファリングされないこと、およびstdout
が完全にバッファリングされる可能性があるのは、対話型デバイスを参照しないと判断できる場合のみであることを指定します(実装によって定義された「対話型デバイス」の意味)。通常、stdout
はラインバッファリングされ(iostreamには存在しない概念)、stderr
はバッファリングされませんが、C標準では保証されません(今日は当てはまらない可能性があります。最後に実際に調べたのは20を超えていました数年前)。とにかく、stdout
に転送するだけの実装は、転送先のC実装のルールに従い、_std::cout
_とstdout
への出力が正しい順序で出力されるようにするためにいくつかの手順を実行する必要はありません。 、およびそのstdout
は、Cの規則に従っているかのように動作します。
パフォーマンスが心配な場合は、いくつかのトライアルを実行することをお勧めします。自分で開いた_std::ofstream
_に出力するのにかかる時間と、_std::cout
_に出力するのにかかる時間(_sync_with_stdio
_を呼び出した場合と呼び出さない場合の両方)を測定してみてください。出力がリダイレクトされました。違いは興味深いはずです。
C++標準では、すべての入力と出力が、すべての読み取りと書き込みが最終的にCストリームの読み取りと書き込みによって行われたかのように定義されています([iostream.objects.overview])。
ヘッダーは、(27.9.2)で宣言された関数によって提供される標準Cストリームにオブジェクトを関連付けるオブジェクトを宣言し、これらのオブジェクトを使用するために必要なすべてのヘッダーを含みます。
これらのオブジェクトにアタッチされた標準Cストリームの動作については、C標準(§7.19.3)を参照する必要があります。
プログラムの起動時に、3つのテキストストリームが事前定義されており、明示的に開く必要はありません。標準入力(従来の入力を読み取るため)、標準出力(従来の出力を書き込むため)、および標準エラー(診断出力を書き込むため)です。最初に開いたとき、標準エラーストリームは完全にはバッファリングされていません。標準入力ストリームと標準出力ストリームは、ストリームが対話型デバイスを参照していないと判断できる場合にのみ、完全にバッファリングされます。
ここではC99標準から引用していますが、(セクション番号のモジュロ変更)C標準のすべてのバージョンで同じであると合理的に確信しています。
このページによると--- http://www.programmingincpp.com/flush-the-output-stream-buffer.html -std :: coutはバッファリングされています。 cout << ...ステートメントの後、フラッシュされる前にプログラムクラッシュが発生したため、印刷に失敗しました。
cout << "My error or flag message, but it's not flushed, so I never see it";
//system crash!
cout << endl;
私がフォーム here を読んだところ、coutは通常バッファリングされていますが、コンソールなどのインタラクティブな環境に出力されることを検出すると、バッファリングされていない状態にフォールバックします。
したがって、出力をリダイレクトすると(UNIXでは「>」を使用)、バッファリングされた動作が開始されます。
リンクされた投稿で詳細をご覧ください。