c ++のiostreamヘッダーのcout、cerr、clogの違いは何ですか?いつ使用するのですか?


97

私は違いを研究しようとしたcoutcerrおよびclogインターネット上ではなく、完璧な答えを見つけることができませんでした。どちらを使用するかはまだ明確ではありません。誰でも簡単なプログラムを通して私に説明でき、どのプログラムをいつ使うべきかについての完璧な状況を説明できますか?

私が訪れたこのサイト上の小さなプログラムを示しcerrそしてclog、そこの上に得られた出力にも使用して得ることができますcout。だから、私はそれぞれの正確な使い方に戸惑っています。


6
それぞれに、コンピューターが認識したストリームstdoutstdincin)がありstderr、デフォルトで使用されます。私はバッファリングの変更clogだけcerrであると考えています。
クリス

回答:


48

stdoutそしてstderr、彼らの両方がデフォルトでコンソール出力を参照していても、異なるストリームです。それらの1つ(例:)をリダイレクト(パイピング)しても、もう1つにprogram.exe >out.txtは影響しません。

通常、stdout実際のプログラム出力に使用する必要がありますが、すべての情報とエラーメッセージはにstderr出力されるため、ユーザーが出力をファイルにリダイレクトした場合でも、情報メッセージは出力ファイルではなく画面に出力されます。


131

通常はstd::cout、通常の出力、std::cerrエラー、およびstd::clog「ログ」に使用します(これは、何を意味するにせよ)。

主な違いはstd::cerr、他の2つのようにバッファーされないことです。


古いC stdoutとに関連してstderr、にstd::cout対応しstdout、while std::cerrstd::clog両方に対応しますstderrstd::clogバッファリングされている場合を除く)。


私はそれclogもに出力することを読みましたcerr。それに基づいて、どちらを選びますか?clogが通常「ロギング」用である場合、なぜそれをエラーストリームに送りたいのですか?ログはcoutエラーではなく、「通常のログ」(別名)に似ています。
void.pointer 2017

@ void.pointer回答で述べたように、cerrclogはどちらも標準の「エラー」出力を使用しますが、clogバッファリングされているため、のように見えますcout。エラー出力のためにどれを選ぶべきですか?おそらく私がリストできるよりも多くの理由に依存し、ケースごとに決定する必要があります。
一部のプログラマー、

3
「バッファリング」とはどういう意味ですか?
simplename 2018

5
@simplename出力は直接書き込まれず、バッファーがフラッシュされるまでバッファーに保存さます。ファイルまたは端末への出力は歴史的に遅い(端末またはコンソールはまだ遅い)、文字ごとの書き込みは効果的ではなく、バイトのチャンクの書き込みははるかに効果的です。
一部のプログラマー、

14

標準出力ストリーム(cout): クラスのcoutインスタンスですostreamcout通常は表示画面である標準出力デバイスで出力を生成するために使用されます。画面に表示する必要のあるデータはcout、挿入演算子(<<)を使用して標準出力ストリーム()に挿入されます。

バッファなしの標準エラーストリーム(cerr): cerrエラーの出力に使用される標準エラーストリームです。これもostreamクラスのインスタンスです。以下のようcerrである非バッファリングされ、我々はすぐにエラーメッセージを表示する必要がある場合、それが使用されるように。エラーメッセージを保存して後で表示するためのバッファはありません。

バッファ付き標準エラーストリーム(clog):これもostreamクラスのインスタンスであり、エラーを表示するために使用されますがcerr、エラーは最初にバッファに挿入され、完全に満たされなくなるまでバッファに格納されます。

さらに読む:basic-input-output-c


11

これら3つのストリームの違いはバッファリングです。

  1. cerrを使用すると、出力がフラッシュします
    • 即時(cerrはバッファーを使用しないため)。
  2. clogを使用すると、出力がフラッシュします
    • 現在の機能を終了した後。
    • 関数flushを明示的に呼び出します。
  3. coutを使用すると、出力がフラッシュされます
    • 出力ストリーム(cout、cerr、clog)を呼び出した後。
    • 現在の機能を終了した後。
    • 関数flushを明示的に呼び出します。

次のコードを確認し、DEBUGを3行で実行してください:f(std :: clog)、f(std :: cerr)、f(std :: out)、3つの出力ファイルを開いて何が起こったかを確認してください。これらの3行を入れ替えて、何が起こるかを確認できます。

#include <iostream>
#include <fstream>
#include <string>

void f(std::ostream &os)
{
    std::cin.clear(); // clear EOF flags
    std::cin.seekg(0, std::cin.beg); // seek to begin

    std::string line;
    while(std::getline(std::cin, line))   //input from the file in.txt
        os << line << "\n";   //output to the file out.txt
}

void test()
{
    std::ifstream in("in.txt");
    std::ofstream out("out.txt"), err("err.txt"), log("log.txt");
    std::streambuf *cinbuf = std::cin.rdbuf(), *coutbuf = std::cout.rdbuf(), *cerrbuf = std::cerr.rdbuf(),
                    *clogbuf = std::clog.rdbuf();

    std::cin.rdbuf(in.rdbuf()); //redirect std::cin to in.txt!
    std::cout.rdbuf(out.rdbuf()); //redirect std::cout to out.txt!
    std::cerr.rdbuf(err.rdbuf());
    std::clog.rdbuf(log.rdbuf());


    f(std::clog);
    f(std::cerr);
    f(std::cout);

    std::cin.rdbuf(cinbuf);
    std::cout.rdbuf(coutbuf);
    std::cerr.rdbuf(cerrbuf);
    std::clog.rdbuf(clogbuf);
}

int main()
{
    test();
    std::cout << "123";
}

10
  • 標準出力にはcoutを使用します。
  • エラーを表示するには、cerrを使用します。
  • ロギングにはclogを使用します。

6
誤っているため、非バッファーのため、cerrはcoutよりも低速です。write vs printfと同じように
陳力

4

C ++ 17標準草案から:

30.4.3ナローストリームオブジェクト[narrow.stream.objects]

istream cin;

1オブジェクトは、(30.11.1)で宣言されたcin、オブジェクトstdinに関連付けられたストリームバッファからの入力を制御します<cstdio>

2オブジェクトcinが初期化された後、をcin.tie()返します&cout。それ以外の状態は、basic_ios<char>::init(30.5.5.2)で必要なものと同じです。

ostream cout;

3オブジェクトは、(30.11.1)で宣言されたcout、オブジェクトstdoutに関連付けられたストリームバッファへの出力を制御します<cstdio>

ostream cerr;

4オブジェクトは、(30.11.1)で宣言されたcerr、オブジェクトstderrに関連付けられたストリームバッファへの出力を制御します<cstdio>

5オブジェクトcerrが初期化された後、cerr.flags() & unitbufはゼロ以外でをcerr.tie()返します&cout。それ以外の状態は、basic_ios<char>::init(30.5.5.2)で必要なものと同じです。

ostream clog;

6オブジェクトは、(30.11.1)で宣言されたclog、オブジェクトstderrに関連付けられたストリームバッファへの出力を制御します<cstdio>

討論...

coutに書き込みstdoutます。cerrclogstderr

標準stdout出力()は、プログラムからエラーや診断以外の出力を受け取ることを目的としています。たとえば、エンドユーザーに表示したり、いくつかの処理ステージにストリーミングしたりできる正常な処理からの出力です。

標準エラー(stderr)は、プログラムがユーザーの期待する出力を生成していない、または生成していない可能性があることを示す警告やエラーメッセージなどの診断出力を目的としています。この入力は、出力データが次の処理ステージにパイプされる場合でも、エンドユーザーに表示されます。

cincerr結びついているcout

両方とも、coutI / O操作自体を処理する前にフラッシュします。これにより、に送信されたプロンプトcoutが、プログラムがから入力を読み取るのをブロックする前に表示され、を介してエラーを書き込む前にcinへの以前の出力coutがフラッシュされますcerr。これにより、両方が同じ端末/ファイル/に送信された場合に、メッセージが生成順に発生します。等..

これとは対照的clogです-そこに書き込むと、バッファーに入れられず、何にも関連付けられないため、フラッシュする前に適切なサイズのロギングをバッファーに入れます。これにより、メッセージのスループットが最も高くなりますが、ターミナルを読んだりログをテーリングしたりするコンシューマーにはメッセージがすぐに表示されない可能性があります。


1

coutclogはどちらもバッファーに入れられますが、cerrはバッファーに入れられず、これらはすべて事前定義されたオブジェクトであり、クラスostreamのインスタンスです。これら3つの基本的な使用法は、coutが標準入力に使用されるのに対し、clogおよびcerrはエラーの表示に使用されます。cerrがバッファリングされない主な理由は、バッファに複数の出力があり、エラー例外がコードに記述されている場合、cerrが効果的に実行できるエラーをすぐに表示する必要があるためです。

私が間違っていたら訂正してください。


-3

coutは通常、一部のステートメントをユーザー画面に表示するために使用されます。ex-:cout << "Arlene Batada";

出力:

アーリーン・バタダ


これはcoutについてのみ言及しており、cerrやclogとの比較は試みていません。OPはcoutの機能を知っています。
JPhi1618 2018年

これは質問に対する答えを提供しません。十分な評判を得ると、どの投稿にもコメントできるようになります。代わりに、質問者からの説明を必要としない回答を提供してください。- レビューから
kometen 2018

@kometenこれは不十分に書かれた答えであっても、質問に答えようとします。代わりに反対票を投じるべきでしたが、反対票は技術的に不正確な場合により適しています。
Cristik
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.