635

多くの C++ 書籍には、次のようなサンプル コードが含まれています...

std::cout << "Test line" << std::endl;

…だから私もずっとそうしてきた。しかし、代わりに次のような作業中の開発者からの多くのコードを見てきました。

std::cout << "Test line\n";

どちらかを優先する技術的な理由はありますか、それとも単にコーディング スタイルの問題ですか?

4

13 に答える 13

528

ファイルがテキストモードで開いていると仮定すると、行末の文字の変化は重要ではありません。これは、バイナリを要求しない限り取得できるものです。コンパイルされたプログラムは、コンパイルされたシステムに対して正しいものを書き出します。

唯一の違いはstd::endl、出力バッファをフラッシュすることとフラッシュ'\n'しないことです。バッファを頻繁にフラッシュしたくない場合は、を使用して'\n'ください。その場合(たとえば、すべての出力を取得したいが、プログラムが不安定な場合)、を使用しますstd::endl

于 2008-10-17T21:56:50.490 に答える
280

違いは次のように説明できます。

std::cout << std::endl;

と同等です

std::cout << '\n' << std::flush;

それで、

  • std::endl出力に即時フラッシュを強制する場合に使用します。
  • パフォーマンスが心配な場合に使用します(演算子\nを使用している場合はおそらくそうではありません)。<<

私は\nほとんどの行で使用します。
次にstd::endl、段落の最後で使用します(ただし、これは単なる習慣であり、通常は必要ありません)。

他の主張とは異なり、\n文字は、ストリームがファイルに送られる場合にのみ、正しいプラットフォームの行末シーケンスにマップされます(std::cinそしてstd::cout、特別であるがファイル(またはファイルのようなもの)である場合のみ)。

于 2008-10-17T22:43:44.513 に答える
45

パフォーマンスの問題が発生している可能性がありstd::endl、出力ストリームを強制的にフラッシュします。

于 2008-10-17T21:28:21.297 に答える
32

使用する場合は、そこに別の関数呼び出しが含まれていますstd::endl

a) std::cout << "Hello\n";
b) std::cout << "Hello" << std::endl;

a) オペレーターを 1 回呼び出します<<
b) オペレーター<<を 2 回呼び出します。

于 2009-11-17T22:29:29.693 に答える
32

これについて標準で読んだことを思い出したので、ここに行きます:

標準ストリームがどのように動作するかを定義する C11 標準を参照してください。C++ プログラムが CRT とやり取りするため、ここでは C11 標準がフラッシュ ポリシーを管理する必要があります。

ISO/IEC 9899:201x

7.21.3 §7

プログラムの起動時に、3 つのテキスト ストリームが事前定義されており、明示的に開く必要はありません。標準入力 (従来の入力を読み取るため)、標準出力 (従来の出力を書き込むため)、および標準エラー (診断出力を書き込むため) です。最初に開いたとき、標準エラー ストリームは完全にバッファリングされていません。標準入力および標準出力ストリームは、ストリームが対話型デバイスを参照していないと判断できる場合にのみ、完全にバッファリングされます。

7.21.3 §3

ストリームがバッファリングされていない場合、文字はソースまたは宛先からできるだけ早く表示されるように意図されています。そうしないと、文字が蓄積され、ブロックとしてホスト環境との間で送受信される可能性があります。ストリームが完全にバッファリングされている場合、文字は、バッファがいっぱいになったときにブロックとしてホスト環境との間で送受信されることを意図しています。ストリームが行バッファリングされている場合、文字は、改行文字が検出されたときにブロックとしてホスト環境との間で送受信されることを意図しています。さらに、文字は、バッファがいっぱいになったとき、バッファされていないストリームで入力が要求されたとき、またはホスト環境からの文字の送信を必要とするラインバッファ付きストリームで入力が要求されたときに、ブロックとしてホスト環境に送信されることを意図しています。 .

これは、非対話型デバイスを参照している場合にのみ、std::coutstd::cinが完全にバッファリングされることを意味します。つまり、stdout が端末に接続されている場合、動作に違いはありません。

ただし、std::cout.sync_with_stdio(false)が呼び出された場合'\n'、対話型デバイスに対してもフラッシュは発生しません。それ以外の場合は、ファイルにパイプしない限り'\n'と同等です: c++ ref on std::endlstd::endl

于 2014-08-29T13:58:14.080 に答える
20

どちらも適切な行末文字を書き込みます。その endl に加えて、バッファがコミットされます。不要なコミットがパフォーマンスに影響を与える可能性があるため、通常、ファイル I/O を実行するときに endl を使用することは望ましくありません。

于 2008-10-17T21:33:32.207 に答える
12

大したことではありませんが、endl はboost::lambdaでは機能しません。

(cout<<_1<<endl)(3); //error

(cout<<_1<<"\n")(3); //OK , prints 3
于 2009-02-22T01:57:21.803 に答える
12

Qt と を使用すると、間違ったものをendl誤って使用してしまう可能性があり、endl非常に驚​​くべき結果が得られます。次のコード スニペットを参照してください。

#include <iostream>
#include <QtCore/QtCore> 
#include <QtGui/QtGui>

// notice that there is no "using namespace std;"
int main(int argc, char** argv)
{
    QApplication qapp(argc,argv);
    QMainWindow mw;
    mw.show();
    std::cout << "Finished Execution!" << endl;
    // This prints something similar to: "Finished Execution!67006AB4"
    return qapp.exec();
}

endl私が代わりに書いたことに注意してくださいstd::endl(これは正しいでしょう)、どうやらqtextstream.h(QtCoreの一部)でendl定義された関数があるようです。

潜在的な名前空間の問題を完全に回避する"\n"代わりに使用します。endlこれは、(Qt がデフォルトで行うように) シンボルをグローバル名前空間に入れることがなぜ悪い考えなのかの良い例でもあります。

于 2010-02-17T01:21:12.987 に答える
2

std::endl は見やすいため、常に使用する習慣がありました。

于 2008-10-17T21:53:29.717 に答える
2

自分のラップトップ以外でプログラムを実行する場合は、決してこのendlステートメントを使用しないでください。特に、短い行をたくさん書いている場合や、1 つの文字をファイルに書き込んでいることがよくあります。の使用は、endlNFS のようなネットワーク化されたファイル システムを強制終了することが知られています。

于 2018-10-27T23:32:02.223 に答える