Frage

Ich habe mich gefragt: Was ist der Sinn einer Verstopfung?Soweit ich das beurteilen kann, ist Clog dasselbe wie Cerr, verfügt jedoch über eine Pufferung, sodass es effizienter ist.Normalerweise ist stderr dasselbe wie stdout, also ist clog dasselbe wie cout.Das scheint mir ziemlich lahm zu sein, daher vermute ich, dass ich es falsch verstehe.Wenn Protokollmeldungen an denselben Ort gesendet werden, an den auch Fehlermeldungen gesendet werden (vielleicht an etwas in /var/log/messages), dann schreibe ich wahrscheinlich nicht zu viel aus (es geht also nicht viel verloren, wenn ich non verwende). -gepufferter Cerr).Meiner Erfahrung nach möchte ich, dass meine Protokollmeldungen auf dem neuesten Stand sind (nicht gepuffert), damit ich bei der Suche nach einem Absturz helfen kann (ich möchte also nicht die gepufferte Verstopfung verwenden).Anscheinend sollte ich immer cerr verwenden.

Ich möchte in der Lage sein, Verstopfungen innerhalb meines Programms umzuleiten.Es wäre nützlich, cerr umzuleiten, damit ich beim Aufrufen einer Bibliotheksroutine steuern kann, wohin cerr und clog gehen.Können einige Compiler dies unterstützen?Ich habe gerade DJGPP überprüft und stdout ist als Adresse einer FILE-Struktur definiert, daher ist es illegal, so etwas wie „stdout = freopen(...)“ zu tun.

  • Ist es möglich, clog, cerr, cout, stdin, stdout und/oder stderr umzuleiten?
  • Ist der einzige Unterschied zwischen Clog und Cerr die Pufferung?
  • Wie sollte ich eine robustere Protokollierungsfunktion implementieren (oder finden) (Links bitte)?
War es hilfreich?

Lösung

Ist es möglich, clog, cerr, cout, stdin, stdout und/oder stderr umzuleiten?

Ja.Du willst das rdbuf Funktion.

ofstream ofs("logfile");
cout.rdbuf(ofs.rdbuf());
cout << "Goes to file." << endl;

Ist der einzige Unterschied zwischen Clog und Cerr die Pufferung?

Soweit ich weiß, ja.

Andere Tipps

Wenn Sie sich in einer POSIX -Shell -Umgebung befinden (ich denke wirklich an Bash), können Sie jeden Dateideskriptor zu einem anderen Dateideskriptor umleiten.

$ myprogram 2>&5 

um stderr auf die durch fd=5 dargestellte Datei umzuleiten.

Bearbeiten:Beim zweiten Nachdenken gefällt mir die Antwort von @Konrad Rudolph zur Umleitung besser.rdbuf() ist eine kohärentere und portablere Möglichkeit, dies zu tun.

Was die Protokollierung betrifft, nun ja ... ich beginne mit der Boost-Bibliothek für alles, was mit C++ zu tun hat, was nicht in der Standardbibliothek enthalten ist.Erblicken: Boost Logging v2

Bearbeiten:Boost Logging ist nicht Teil der Boost-Bibliotheken;Es wurde überprüft, aber nicht akzeptiert.

Bearbeiten:Zwei Jahre später, im Mai 2010, akzeptierte Boost eine Protokollierungsbibliothek, die jetzt „ Boost.Log.

Natürlich gibt es Alternativen:

  • Log4Cpp (eine API im Log4j-Stil für C++)
  • Log4Cxx (Von Apache gesponserte API im Log4j-Stil)
  • Pantheios (verstorben?Als ich es das letzte Mal versuchte, konnte ich es nicht auf einem neueren Compiler aufbauen.)
  • Googles GLog (hat-tip @SuperElectric)

Es gibt auch den Windows-Ereignislogger.

Und ein paar Artikel, die nützlich sein könnten:

Einfacher Logger

#define myerr(e) {CriticalSectionLocker crit; std::cerr << e << std::endl;}

Benutzt als myerr("ERR: " << message); oder myerr("WARN: " << message << code << etc);

Ist sehr effektiv.

Dann mach:

./programname.exe 2> ./stderr.log
perl parsestderr.pl stderr.log

oder analysieren Sie einfach stderr.log von Hand

Ich gebe zu, das ist nichts dafür äußerst leistungskritischer Code.Aber wer schreibt das schon?

Da es hier mehrere Antworten zur Umleitung gibt, werde ich hinzufügen dieses schöne Juwel Ich bin kürzlich über die Umleitung gestolpert:

#include <fstream>
#include <iostream>

class redirecter
{
public:
    redirecter(std::ostream & dst, std::ostream & src)
        : src(src), sbuf(src.rdbuf(dst.rdbuf())) {}
    ~redirecter() { src.rdbuf(sbuf); }
private:
    std::ostream & src;
    std::streambuf * const sbuf;
};

void hello_world()
{
    std::cout << "Hello, world!\n";
}

int main()
{
    std::ofstream log("hello-world.log");
    redirecter redirect(log, std::cout);
    hello_world();
    return 0;
}

Es handelt sich im Grunde um eine Umleitungsklasse, die es Ihnen ermöglicht, zwei beliebige Streams umzuleiten und sie wiederherzustellen, wenn Sie fertig sind.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top