C ++:“ std :: endl” vs“ \ n”
-
03-07-2019 - |
質問
多くのC ++ブックには、次のようなサンプルコードが含まれています...
std::cout << "Test line" << std::endl;
...しかし、代わりにこのような作業中の開発者から多くのコードを見てきました:
std::cout << "Test line\n";
一方を他方よりも優先する技術的な理由はありますか、それともコーディングスタイルの問題ですか?
解決
ファイルがテキストモードで開かれていると仮定すると、さまざまな行末文字は重要ではありません。これは、バイナリを要求しない限り得られるものです。コンパイルされたプログラムは、コンパイルされたシステムに適したものを書き出します。
唯一の違いは、 std :: endl
は出力バッファーをフラッシュし、 '\ n'
はフラッシュしません。バッファを頻繁にフラッシュしたくない場合は、 '\ n'
を使用します。実行する場合(たとえば、すべての出力を取得する必要があり、プログラムが不安定な場合)、 std :: endl
を使用します。
他のヒント
違いは次のように説明できます:
std::cout << std::endl;
は同等です
std::cout << '\n' << std::flush;
だから、
- 出力への即時フラッシュを強制する場合は、
std :: endl
を使用します。 - パフォーマンスが心配な場合は
\ n
を使用します(&lt;&lt;
演算子を使用している場合はおそらくそうではありません)。
ほとんどの行で \ n
を使用しています。
次に、段落の最後で std :: endl
を使用します(ただし、これは単なる習慣であり、通常は必要ありません)。
他の主張とは異なり、 \ n
文字は、ストリームがファイル( std :: cin
)に向かう場合にのみ、正しいプラットフォームの行末シーケンスにマップされます。および std :: cout
は特別ですが、まだファイル(またはファイルのようなもの)です。
パフォーマンスの問題がある可能性があります。 std :: endl
は出力ストリームのフラッシュを強制します。
標準でこれについて読んだことを思い出したので、ここに行きます:
標準ストリームの動作を定義するC11標準を参照してください。C++プログラムはCRTとインターフェイスするため、C11標準はここでフラッシュポリシーを管理する必要があります。
ISO / IEC 9899:201x
7.21.3&#167; 7
プログラムの起動時に、3つのテキストストリームが事前に定義されており、明示的に開く必要はありません &#8212;標準入力(従来の入力の読み取り用)、標準出力(書き込み用) 従来の出力)、および標準エラー(診断出力の書き込み用)。最初のように オープンすると、標準エラーストリームは完全にバッファリングされません。標準入力および標準 ストリームが参照しないと判断できる場合にのみ、出力ストリームは完全にバッファリングされます インタラクティブなデバイスに。
7.21.3&#167; 3
ストリームがバッファリングされていない場合、文字はソースから、または できるだけ早く目的地。そうしないと、文字が蓄積されたり、 ホスト環境との間でブロックとして送信されます。ストリームが完全にバッファリングされると、 文字は、ホスト環境との間でブロックとして送信されることを目的としています。 バッファがいっぱいです。ストリームがラインバッファリングされる場合、文字は 改行文字が次の場合、ホスト環境との間でブロックとして送信されます。 遭遇しました。さらに、文字はブロックとしてホストに送信されることを意図しています バッファがいっぱいになったとき、入力がバッファされていないストリームで要求されたとき、または 入力の送信が必要なラインバッファストリームで要求された場合 ホスト環境からの文字。これらの特性のサポートは 実装定義であり、setbufおよびsetvbuf関数によって影響を受ける可能性があります。
これは、 std :: cout
と std :: cin
が完全にバッファリングされていることを意味します。インタラクティブなデバイス。つまり、stdoutが端末に接続されている場合、動作に違いはありません。
ただし、 std :: cout.sync_with_stdio(false)
が呼び出された場合、 '\ n'
は対話型デバイスに対してもフラッシュを引き起こしません。それ以外の場合、 '\ n'
は、ファイルにパイピングしない限り std :: endl
と同等です: std :: endlのc ++参照。
std :: endl
a) std::cout << "Hello\n";
b) std::cout << "Hello" << std::endl;
a)演算子&lt;&lt;
を1回呼び出します。
b)演算子&lt;&lt;
を2回呼び出します。
これらは両方とも適切な行末文字を書き込みます。そのendlに加えて、バッファーがコミットされます。不要なコミットはパフォーマンスに影響を与える可能性があるため、通常、ファイルI / Oを実行するときにendlを使用することは望ましくありません。
大したことではないが、 endlは機能しません boost :: lambda で。
(cout<<_1<<endl)(3); //error
(cout<<_1<<"\n")(3); //OK , prints 3
Qtとendlを使用している場合、間違った endl
を誤って使用する可能性があります。これは今日私に起こり、私は..WTF ??
#include <iostream>
#include <QtCore/QtCore>
#include <QtGui/QtGui>
//notice that i dont have a "using namespace std;"
int main(int argc, char** argv)
{
QApplication qapp(argc,argv);
QMainWindow mw;
mw.show();
std::cout << "Finished Execution !" << endl << "...";
// Line above printed: "Finished Execution !67006AB4..."
return qapp.exec();
}
もちろんそれは私の間違いでした。 std :: endl
を書くべきだったので、、 * endl
、qt、および using namespace std;
正しい endl
が使用されるかどうかは、インクルードファイルの順序に依存します。
もちろん、Qtを再コンパイルして名前空間を使用できるため、上記の例ではコンパイルエラーが発生します。
編集:言及するのを忘れましたが、Qtの endl
は&quot; qtextstream.h&quot;で宣言されています。 QtCoreの一部です
* EDIT2: std :: cout
または名前空間 stdに
、 using
がある場合、C ++は正しい endl
を選択します std :: endl
は std :: cout
と同じ名前空間にあるため、C ++のADLメカニズムは std :: endl
。
見やすいので、常にstd :: endlを使用する習慣がありました。
参照これは出力専用ですI / Oマニピュレーター。
std :: endl
出力シーケンスosに改行文字を挿入し、 os.put(os.widen( '\ n '))
の後に os.flush()
が続きます。
使用する場合:
このマニピュレーターは、すぐに出力の行を生成するために使用できます。
e.g。
長時間実行プロセスからの出力を表示するとき、複数のスレッドのアクティビティを記録する、または予期せずクラッシュする可能性のあるプログラムのアクティビティを記録する。
また
生成されたプロセスが画面I / Oを実行する場合、std :: systemを呼び出す前に、std :: coutの明示的なフラッシュも必要です。他のほとんどの通常の対話型I / Oシナリオでは、std :: cinからの入力、std :: cerrへの出力、またはプログラムの終了によりstd :: coutが強制的に呼び出されるため、std :: endlをstd :: coutと併用すると冗長になります。流す()。 '\ n'の代わりにstd :: endlを使用すると、一部のソースによって奨励され、出力パフォーマンスが大幅に低下する可能性があります。
自分のラップトップ以外でプログラムを実行する場合は、 endl
ステートメントを使用しないでください。特に、多くの短い行を書いている場合、またはファイルに単一の文字をよく見た場合。 endl
を使用すると、NFSなどのネットワーク化されたファイルシステムを強制終了できます。
endl
マニピュレーターは '\'
と同等です。ただし、 endl
は常にストリームをフラッシュします。
std::cout << "Test line" << std::endl; // with flush
std::cout << "Test line\n"; // no flush
気付かなかった場合、 endl
はEnterキーを押すようなもので、&quot; \ n&quot;
はEnterキー+スペースバーを押すようなものです。