多くのC ++の本には、このようなサンプルコードが含まれています...
std::cout << "Test line" << std::endl;
...だから私もいつもそうしている。しかし、代わりに次のような作業中の開発者からの多くのコードを見てきました。
std::cout << "Test line\n";
どちらかを優先する技術的な理由はありますか、それともコーディングスタイルの問題ですか?
'\n'
ます。
多くのC ++の本には、このようなサンプルコードが含まれています...
std::cout << "Test line" << std::endl;
...だから私もいつもそうしている。しかし、代わりに次のような作業中の開発者からの多くのコードを見てきました。
std::cout << "Test line\n";
どちらかを優先する技術的な理由はありますか、それともコーディングスタイルの問題ですか?
'\n'
ます。
回答:
ファイルがテキストモードで開いていると仮定すると、さまざまな行末文字は関係ありません。これは、バイナリを要求しない限り得られるものです。コンパイルされたプログラムは、コンパイルされたシステムに適切なものを書き出します。
唯一の違いはstd::endl
、出力バッファーをフラッシュすることとフラッシュ'\n'
しないことです。バッファを頻繁にフラッシュしたくない場合は、を使用してください'\n'
。実行する場合(たとえば、すべての出力を取得する必要があり、プログラムが不安定な場合)は、を使用しますstd::endl
。
::std::cerr
代わりに使用することを検討してください::std::cout
。
stderr
「エラー」用だとは言えません。むしろ、可能であれば、帯域外の診断メッセージ用です。./prog > file
真のプログラムペイロードのみを言って保存することは可能ですが、プログラムは通常の対話であっても、より多くのステータス情報を出力したい場合があります。
違いは次のように説明できます。
std::cout << std::endl;
に相当
std::cout << '\n' << std::flush;
そう、
std::endl
出力をすぐにフラッシュしたい場合に使用します。\n
パフォーマンスが心配な場合に使用します(<<
演算子を使用している場合はおそらくそうではありません)。\n
ほとんどの回線で使用しています。
次にstd::endl
、段落の最後で使用します(ただし、これは単なる習慣であり、通常は必要ありません)。
他の主張とは逆に\n
、ストリームがファイルに送られる場合(std::cin
そしてstd::cout
特別であるがファイル(またはファイルのような)である場合)にのみ、文字は正しいプラットフォームの行末シーケンスにマップされます。
cout
はに関連していますcin
。つまり、から入力を読み取った場合cin
、cout
最初にフラッシュされるためです。しかし、から読み取らずにプログレスバーなどを表示したい場合cin
は、フラッシュが便利です。
operator<<
パフォーマンスが良くないこと、またはパフォーマンスに使用する代替手段がわからないことを知りませんでしたか?これをさらに理解するために私にいくつかの資料を指摘してください。
sync_with_stdio(false)
、出力を継続的にフラッシュしないでください。いつそれを行うべきかライブラリーに考えさせます。stackoverflow.com/a/1926432/14065
パフォーマンスの問題がある可能性がありstd::endl
ます。出力ストリームを強制的にフラッシュします。
あなたが使うつもりならそこに暗黙の別の関数呼び出しがあります std::endl
a) std::cout << "Hello\n";
b) std::cout << "Hello" << std::endl;
a)オペレーターを<<
1回呼び出す。
b)オペレーターを<<
2回呼び出す。
std::cout << "Hello" << "\n";
ですか?
<<
はケースaでも2になるため、1つまたは2つ<<
(または一般的に2つの関数呼び出し)の必要性を要求しません。違い\n
とendl
。
私はこれについて標準で読んだことを思い出したので、ここに行きます:
C ++プログラムがCRTとインターフェースするため、標準ストリームの動作を定義するC11標準を参照してください。C11標準は、ここでフラッシュポリシーを管理する必要があります。
ISO / IEC 9899:201x
7.21.3§7
プログラムの起動時に、3つのテキストストリームが事前定義されており、明示的に開く必要はありません。標準入力(従来の入力を読み取る場合)、標準出力(従来の出力を書き込む場合)、および標準エラー(診断出力を書き込む場合)。最初に開いたとき、標準エラーストリームは完全にバッファリングされていません。ストリームがインタラクティブデバイスを参照しないと判断できる場合に限り、標準入力ストリームと標準出力ストリームは完全にバッファリングされます。
7.21.3§3
ストリームがバッファリングされていない場合、文字はソースから、または宛先にできるだけ早く表示されるようになっています。そうしないと、文字が蓄積され、ホスト環境との間でブロックとして送信されます。ストリームが完全にバッファリングされている場合、文字は、バッファがいっぱいになったときにブロックとしてホスト環境との間で送受信されることを目的としています。ストリームがラインバッファリングされている場合、改行文字が検出されると、文字はホスト環境との間でブロックとして転送されるように意図されています。さらに、バッファがいっぱいになったとき、バッファリングされていないストリームで入力が要求されたとき、またはホスト環境からの文字の送信を必要とするラインバッファリングストリームで入力が要求されたときに、文字はブロックとしてホスト環境に送信されるように意図されています。 。
これは、非対話型デバイスを参照している場合に限り、完全にバッファリングされることstd::cout
を意味します。つまり、端末にstdoutが接続されている場合、動作に違いはありません。std::cin
ただし、std::cout.sync_with_stdio(false)
が呼び出された場合、'\n'
インタラクティブデバイスに対してもフラッシュは発生しません。それ以外の場合'\n'
はstd::endl
、ファイルへのパイプを行わない場合と同等です:c ++ ref on std :: endl。
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
そして明らかendl
にqtextstream.hで定義された関数があります(これはQtCoreの一部です)で。
名前空間の潜在的な問題"\n"
をendl
完全に回避する代わりに使用する。これは、シンボルをグローバル名前空間に配置すること(Qtがデフォルトで行うように)が悪い考えである良い例でもあります。
using namespace std;
か?:-)
using namespace std;
。それは悪い習慣と考えられています。「名前空間stdを使用する理由」を
私は常にstd :: endlを使用する癖がありました。
で参照これは出力専用I / Oマニピュレータ。
std::endl
改行文字を出力シーケンスosに挿入し、os.put(os.widen('\n'))
次にを呼び出した場合と同様にフラッシュしos.flush()
ます。
いつ使用するか:
このマニピュレータを使用して、出力行をすぐに生成できます。
例えば
長時間実行されているプロセスからの出力を表示する場合、複数のスレッドのログアクティビティまたは予期せずクラッシュする可能性のあるプログラムのログアクティビティ。
また
生成されたプロセスが画面I / Oを実行する場合、std :: systemを呼び出す前にstd :: coutの明示的なフラッシュも必要です。他のほとんどの通常の対話式I / Oシナリオでは、std :: cinからの入力、std :: cerrへの出力、またはプログラムの終了によりstd :: coutが強制的に呼び出されるため、std :: coutと共に使用するとstd :: endlは冗長になります。 。流す()。一部のソースから推奨されている「\ n」の代わりにstd :: endlを使用すると、出力パフォーマンスが大幅に低下する可能性があります。