it-swarm.com.de

Was ist der Unterschied zwischen cout, cerr und clog des iostream-Headers in c ++? Wann welche verwenden?

Ich habe versucht, den Unterschied zwischen cout, cerr und clog im Internet zu untersuchen, konnte aber keine perfekte Antwort finden. Ich weiß immer noch nicht, wann ich welche verwenden soll. Kann mir jemand durch einfache Programme erklären und eine perfekte Situation aufzeigen, wann man welches benutzt?

Ich habe diese Seite besucht, die ein kleines Programm für cerr und clog zeigt, aber die dort erhaltene Ausgabe kann auch mit cout abgerufen werden. Ich bin verwirrt über die genaue Verwendung jedes Einzelnen.

78
Arlene Batada

stdout und stderr sind unterschiedliche Streams, obwohl beide standardmäßig auf die Konsolenausgabe verweisen. Umleiten (Leiten) einer von ihnen (z. B. program.exe >out.txt) würde den anderen nicht beeinflussen.

Im Allgemeinen sollte stdout für die eigentliche Programmausgabe verwendet werden, während alle Informationen und Fehlermeldungen in stderr gedruckt werden sollten. Wenn der Benutzer die Ausgabe in eine Datei umleitet, werden weiterhin Informationsnachrichten gedruckt der Bildschirm und nicht auf die Ausgabedatei.

43
riv

Im Allgemeinen verwenden Sie std::cout für normale Ausgabe, std::cerr für Fehler und std::clog für "Protokollierung" (was bedeuten kann, was immer Sie wollen, dass es bedeutet).

Der Hauptunterschied ist, dass std::cerr wird nicht wie die beiden anderen gepuffert.


In Bezug auf die alten C stdout und stderr, std::cout entspricht stdout, während std::cerr und std::clog both entspricht stderr (außer dass std::clog ist gepuffert).

114
  • Verwenden Sie cout für die Standardausgabe.
  • Verwenden Sie cerr, um Fehler anzuzeigen.
  • Verwenden Sie clog zum Protokollieren.
8
David Vargas

Standardausgabestream (cout): cout ist die Instanz der Klasse ostream. cout wird zur Ausgabe auf dem Standardausgabegerät verwendet, bei dem es sich normalerweise um den Anzeigebildschirm handelt. Die Daten, die auf dem Bildschirm angezeigt werden sollen, werden mit dem Einfügeoperator (<<) In den Standardausgabestream (cout) eingefügt.

Ungepufferter Standardfehlerstrom (cerr): cerr ist der Standardfehlerstrom, der zur Ausgabe der Fehler verwendet wird. Dies ist auch eine Instanz der Klasse ostream. Da cerr nicht gepuffert ist , wird es verwendet, wenn die Fehlermeldung sofort angezeigt werden muss. Es hat keinen Puffer, um die Fehlermeldung zu speichern und später anzuzeigen.

Gepufferter Standardfehlerstrom (clog): Dies ist ebenfalls eine Instanz der Klasse ostream und wird zur Anzeige von Fehlern verwendet, im Gegensatz zu cerr Der Fehler wird zuerst in einen Puffer eingefügt und im Puffer gespeichert, bis er nicht mehr vollständig gefüllt ist.

weiterlesen: basic-input-output-c

8
roottraveller

Die Differenz dieser 3 Ströme ist Pufferung.

  1. Mit cerr wird die Ausgabe gespült
    • sofort (weil cerr keinen Puffer verwendet).
  2. Bei Verstopfung wird der Ausgang gespült
    • nachdem Sie Ihre aktuelle Funktion beendet haben.
    • rufen Sie explizit die Funktion flush auf.
  3. Mit cout wird die Ausgabe gespült
    • nachdem Sie einen Ausgabestream aufgerufen haben (cout, cerr, clog).
    • nachdem Sie Ihre aktuelle Funktion beendet haben.
    • rufen Sie explizit die Funktion flush auf.

Überprüfen Sie den folgenden Code und führen Sie DEBUG in drei Zeilen aus: f (std :: clog), f (std :: cerr), f (std :: out). Öffnen Sie dann drei Ausgabedateien, um zu sehen, was passiert ist. Sie können diese 3 Zeilen tauschen, um zu sehen, was passieren wird.

#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";
}
5
Duc-Viet Ha

Aus einem Entwurf eines C++ 17-Standarddokuments:

30.4.3 Narrow-Stream-Objekte [Narrow-Stream-Objekte]

istream cin;

1 Das Objekt cin steuert die Eingabe von einem Stream-Puffer, der dem Objekt stdin zugeordnet ist, das in <cstdio> (30.11.1) deklariert ist.

2 Nachdem das Objekt cin initialisiert wurde, gibt cin.tie()&cout zurück. Der Status ist ansonsten der gleiche wie für basic_ios<char>::init (30.5.5.2).

ostream cout;

3 Das Objekt cout steuert die Ausgabe in einen Stream-Puffer, der dem in <cstdio> (30.11.1) deklarierten Objekt stdout zugeordnet ist.

ostream cerr;

4 Das Objekt cerr steuert die Ausgabe in einen Stream-Puffer, der dem in <cstdio> (30.11.1) deklarierten Objekt stderr zugeordnet ist.

5 Nachdem das Objekt cerr initialisiert wurde, ist cerr.flags() & unitbuf ungleich Null und cerr.tie() gibt &cout zurück. Der Status ist ansonsten der gleiche wie für basic_ios<char>::init (30.5.5.2).

ostream clog;

6 Das Objekt clog steuert die Ausgabe in einen Stream-Puffer, der dem in <cstdio> (30.11.1) deklarierten Objekt stderr zugeordnet ist.

Diskussion...

cout schreibt an stdout; cerr und clog an stderr

Standard Out (stdout) ist für den Empfang fehlerfreier, nicht diagnostischer Ausgaben aus dem Programm vorgesehen, z. B. Ausgaben aus einer erfolgreichen Verarbeitung, die dem Endbenutzer angezeigt oder in eine weitere Verarbeitungsstufe gestreamt werden können.

Standardfehler (stderr) ist für Diagnoseausgaben vorgesehen, z. B. Warnungen und Fehlermeldungen, die angeben, dass das Programm die vom Benutzer erwartete Ausgabe nicht oder möglicherweise nicht erstellt hat. Diese Eingabe kann dem Endbenutzer angezeigt werden, selbst wenn die Ausgabedaten zu einer weiteren Verarbeitungsstufe geleitet werden.

cin und cerr sind an cout gebunden

Sie spülen beide cout, bevor sie die E/A-Operationen selbst ausführen. Dies stellt sicher, dass an cout gesendete Eingabeaufforderungen sichtbar sind, bevor das Programm Eingaben von cin liest, und dass frühere Ausgaben an cout gelöscht werden, bevor ein Fehler durch cerr, wodurch die Nachrichten in chronologischer Reihenfolge ihrer Erzeugung gehalten werden, wenn beide an dasselbe Terminal/dieselbe Datei/usw. gerichtet sind.

Dies steht im Gegensatz zu clog - wenn Sie dort schreiben, wird es nicht gepuffert und ist an nichts gebunden. Daher werden vor dem Leeren ausreichend große Protokollmengen gepuffert. Dies ergibt den höchsten Durchsatz an Nachrichten, bedeutet jedoch, dass die Nachrichten für einen potenziellen Kunden, der das Terminal liest oder das Protokoll verfolgt, möglicherweise nicht schnell sichtbar sind.

3
Tony Delroy

Sowohl cout als auch clog sind gepuffert, aber cerr ist ungepuffert, und alle diese Objekte sind vordefinierte Objekte, die Instanzen des Klassenostreams sind. Die grundlegende Verwendung dieser drei sind cout wird für die Standardeingabe verwendet, während clog und cerr zum Anzeigen von Fehlern verwendet werden. Der Hauptgrund, warum cerr nicht gepuffert ist, kann sein, dass Sie, wenn Sie mehrere Ausgaben im Puffer haben und eine Fehlerausnahme im Code erwähnt wird, diesen Fehler sofort anzeigen müssen, was durch getan werden kann cerr effektiv.

Bitte korrigieren Sie mich, wenn ich falsch liege.

1