web-dev-qa-db-ja.com

「\ n」または「\ n」またはstd :: endlからstd :: cout?

std::endlへの書き込み時にstd::coutを使用して行を終了するのをやめて、代わりに"\n"を使用し始めてから何年も経ちました。

しかし、今では、代わりに'\n'を使用してコードのスニペットが増え始め、何が最適なのか疑問に思い始めました。

一方が文字列で、もう一方が文字であることは明らかであることに加えて、これを使用する利点はあります

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

これについて:

std::cout << variable << "\n";

後期追加:

この質問をしたとき、改行'\n'がバッファをフラッシュしたと思いました。これでdependsであることがわかりました。

デフォルトでは、std::cinは古いC stdinFILE*ストリームに関連付けられ、std::coutstdoutに関連付けられています。改行のフラッシュは、この結び付けから生じます。デフォルトでは、stdoutは、端末に接続されている場合、ラインバッファリングされます。つまり、新しい行はそのバッファーをフラッシュします。したがって、std::coutを使用して改行を印刷すると、stdoutがフラッシュされます。

stdoutが端末に接続されていない場合(たとえば、出力がリダイレクトされているか、パイプされている場合)、またはstd::coutstdoutの関係が壊れている場合、改行はありません何でもフラッシュします。

91

実際、'\n'がデフォルトです。ストリームを明示的にフラッシュする場合(およびいつ、なぜそれを行うのか)を除き、std::endlを使用する必要はまったくありません。1
もちろん、多くの本やチュートリアルではstd::endlをデフォルトとして使用しています。それは残念であり、 深刻なパフォーマンスバグ につながる可能性があります。

'\n'を使用する場合と"\n"を使用する場合にほとんど違いはないと思いますが、後者は(2つの)文字の配列であり、文字ごとに印刷する必要があり、ループを設定する必要があります、単一の文字を出力するよりも複雑です。もちろん、IOを実行する場合、これはめったに重要ではありませんが、疑わしい場合は、1つの文字リテラルを出力する場合、文字列リテラル全体ではなく文字リテラルを出力します。
そうすることの良い副作用は、コード内で、意図したことを伝え、偶然これをやっただけです。


1std::coutはデフォルトでstd::cinに関連付けられているため、入力操作の前にstd::coutがフラッシュされるため、ユーザーが何かを入力する前にプロンプ​​トが出力されます。

101
sbi

最高はありません。必要なものを使用します。

  • '\ n'-行を終了します
  • "some string\n"-ある文字列の後の行の終わり
  • std::endl-行を終了してストリームをフラッシュする
14
BЈовић

彼らは異なることをします。 "\n"は改行を出力します(適切なプラットフォーム固有の表現で、Windowsでは"\r\n"を生成します)が、std::endlは同じことを行いますおよびストリームをフラッシュします 。通常、すぐにストリームをフラッシュする必要はなく、パフォーマンスが低下するだけなので、ほとんどの場合、std::endlを使用する理由はありません。

14
jalf
  • _std::cout << variable << std::endl;_

    _std::endl_は改行を出力しますが、出力ストリームもフラッシュします。つまり、と同じ効果

    _std::cout << variable << '\n'; // output newline
    std::cout.flush();      // then flush 
    _
  • _std::cout << variable << '\n';_

    _'\n'_は_char,_の改行を出力するため、ostream& operator<< (ostream& os, char c);が使用されます。

  • _std::cout << variable << "\n";_

    _"\n"_は_const char[2]_であるため、ostream& operator<< (ostream& os, const char* s);が使用されます。この関数にはループが含まれることを想像できますが、改行を印刷するだけではやり過ぎだと主張するかもしれません。

4
zangw

編集:私は自分の答えを粗末に言いました。それは、「\ n」が実際にヌル文字を印刷すると思ったと人々に信じさせるかもしれません。これはもちろん間違っています:)

編集2:C++リファレンスを見て、charsは参照によって渡されるので、違いはありません。唯一の違いは、区切り文字を検索するためにcstringを検索する必要があることです。 この事実により、以下は正しくありません。

'\n'"\n"よりも非常にわずかに効率的です。後者は最後にヌル文字も含むため、char*operator<<()に送信することを意味します(32ビットシステムでは通常4バイト)charの単一バイトとは異なります。

実際には、これは境界線とは無関係です。個人的に、私はウラジミールが概説した慣習に従います。*

4
Chris Parton

std::endlはストリームをフラッシュします。これがあなたが起こしたいとき-例えば出力がタイムリーにユーザーに表示されることを期待しているため、ストリームにstd::endlを書き込む代わりに'\n'を使用する必要があります(分離文字または文字列の一部として)。

時には、ストリームを自分で明示的にフラッシュせずに逃げることができます。例えばLinux環境では、coutSTDOUTと同期され(これがデフォルトです)、端末に書き込みを行っている場合、デフォルトでは、ストリームはline bufferedになります。 =そして、新しい行を書き込むたびに自動的にフラッシュします。

ただし、この動作に依存するのは危険です。例えば同じLinux環境で、stdoutをファイルにリダイレクトするか別のプロセスにパイプしてプログラムを実行する場合、デフォルトでは、ストリームはblock bufferedになります。

同様に、後で効率化のためにstdioとの同期をオフにすることにした場合、実装はiostreamのバッファリングメカニズムを使用する傾向があります。これには、ラインバッファリングモードがありません。

この間違いにより、生産性が大幅に低下しています。書き込み時に出力を表示する必要がある場合は、std::endlを明示的に使用する(またはstd::flushまたはstd::ostream::flushを使用する必要がありますが、通常はstd::endlがより便利です) stdoutを行バッファリングするように設定するなど、十分な頻度でフラッシュが行われることを保証する何か他のことを行います(適切であると仮定)。

3
Hurkyl