9 Stimmen

Wie kann man die printf-Ausgabe zurück in den Code umleiten?

Ich schreibe eine kleine C++-Anwendung um die opencv haar-Trainingsfunktion (nämlich cvCreateTreeCascadeClassifier) zu wickeln. Die Funktion wirft eine ganze Ladung von Ausgabe auf der Konsole und ich möchte diese Ausgabe zu analysieren, so dass ich verschiedene Variablen in meinem Code auffüllen kann.

Die Funktion, die ich verwenden möchte, ist nicht Teil der eigentlichen openCV-Bibliothek; stattdessen muss sie mit meinem Code als Teil des Projekts gebaut werden. Die gesamte Ausgabe der Funktion erfolgt über printf.

Frage: Ist es möglich, die printf-Anweisungen abzufangen, bevor sie auf der Konsole landen? Ich habe es geschafft, sie mit freopen umzuleiten, aber das scheint ein wenig ungeschickt, da ich dann die Datei parsen und dann löschen muss, wenn der Funktionsaufruf beendet ist. Außerdem wird die Funktion wahrscheinlich für mehrere Stunden (und möglicherweise sogar Wochen!) ausgeführt werden, so dass die Größe der Datei ein Problem sein könnte, wenn seine ständig angehängt werden zu.

Anforderungen: Die Anwendung muss in C++ geschrieben sein und sowohl unter Windows als auch unter Linux laufen (aber ich habe kein Problem mit bedingten Kompilieranweisungen, wenn es sein muss). Ich möchte auch in der Lage sein, noch meine cout und cerr Nachrichten auf der Konsole zu sehen (nur nicht die printf).

Mein Googeln hat mir den Lebenswillen genommen! Kann jemand mit einer Lösung helfen, entweder durch ein Codebeispiel oder durch Hinweise auf Stellen, an denen ich nach einer Antwort suchen sollte?

Danke

7voto

Nordic Mainframe Punkte 27006

Was Sie tun können, ist:

  • ein Rohr erstellen
  • das beschreibbare Ende der Pipe zum neuen stdout machen
  • Lesen aus dem lesbaren Teil der Pipe

Lesen und Schreiben sollten in verschiedenen Threads erfolgen, sonst riskieren Sie, dass Ihr Programm an einem Ende der Pipe verhungert.

Hier ein Beispiel, wie die Umleitung unter Unix und Windows funktioniert:


#include <fcntl.h>
#include <stdlib.h>
#include <stdio.h>
/* gcc defined unix */
#ifdef unix
#include <unistd.h>
#endif
#ifdef WIN32
#include <io.h>
#define pipe(X) _pipe(X,4096,O_BINARY)     
#define fileno _fileno
#define dup2 _dup2
#define read _read

#endif
#include <assert.h>

int main()
{
    int fds[2]; 
    int res; 
    char buf[256];
    int so; 

    res=pipe(fds);
    assert(res==0); 

    so=fileno(stdout);
    // close stdout handle and make the writable part of fds the new stdout.
    res=dup2(fds[1],so);
    assert(res!=-1); 

    printf("Hi there\n");
    fflush(stdout);
    // reading should happen in a different thread

    res=read(fds[0],buf,sizeof(buf)-1);
    assert(res>=0 && res<sizeof(buf));
    buf[res]=0;
    fprintf(stderr,"buf=>%s\n",buf);
    return 0;
}

Dieser Code sollte Folgendes ausgeben

buf=>Hi there

(Ich verwende hier Assert, weil ich zu faul bin, eine echte Fehlerprüfung für dieses Beispiel durchzuführen)

0voto

Ozair Kafray Punkte 13142

Kapseln Sie die Bibliothek in eine Anwendung und leiten Sie die Ausgabe der Anwendung an Ihre Anwendung weiter. Schreiben Sie nun ein Skript, damit Sie die Anwendungen nicht jedes Mal zusammen mit einer Pipe ausführen müssen.

0voto

RedX Punkte 14129

Schauen Sie sich das an: http://www.unix.com/programming/136225-reading-stdout-pipe.html Es scheint vielversprechend zu sein, aber ich habe es nie ausprobiert.

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X