C: Ausgabe eines Programms auswerten

  • Hi,


    gibt es in C eine effizientere Möglichkeit, die Ausgabe eines Programms nach stdout einzulesen als per "./programm >output" und danach das File output zu parsen? So ala cin oder so..


    Joe

  • Z.b mit popen !


    Aus der Man-Page:


    main()
    {
    char *cmd = "/usr/bin/ls *.c";
    char buf[BUFSIZ];
    FILE *ptr;


    if ((ptr = popen(cmd, "r")) != NULL)
    while (fgets(buf, BUFSIZ, ptr) != NULL)
    (void) printf("%s", buf);
    (void) pclose(ptr);
    return 0;
    }

  • Müsste sich in dem von dir genanntem Beispiel die while-Schleife nicht so auswirken, das nach und nach die BUFSIZ Bytes der Ausgabe eingelesen werden? Bei mir ist es so, das ich in einer Endlosschleife hängen bleibe... Die Ausgabe ist eine Zeile lang und ich lese nur einen Bruchteil an Zeichen ein. Jedesmal spuckt er mir die selben aus.


    Joe

  • Ups, sorry mein Fehler. Dennoch wie schaffe ich es, das er mir nach und nach die Ausgabe einliest. Beispiel:
    Ausgabe wäre: "Das ist eine lange Ausgabe und man muss Sie in mehreren Schritten einlesen!"
    Nun möchte ich davon (da mir die Länge a priori nicht bekannt ist) immer x Zeichen nach und nach einlesen. Geht das?


    Joe

    Einmal editiert, zuletzt von mrjoe ()

  • Tust Du doch bereits, eine Zeile pro Schleifendurchlauf, wobei Zeilen die länger als BUFSIZ sind aufgespalten werden.


    Wenn Du unter GNU programmierst, empfehle ich die getline-Funktion, die allokiert Dir immer genau genug für eine ganze Zeile, egal wie lang diese ist.


  • Hmm, da muss ich widersprechen. Im Moment liest er mir immer die ersten BUFSIZ Zeichen ein. Und wenn es mal <BUFSIZ Zeichen sind, dann lese ich im "undefinierten" Bereich dahinter. Das ist ungünstig.


    Joe

  • Sorry, aber - nö ;)


    fgets liest maximal size Zeichen in buffer ein. Der buffer wird nullterminiert. Lesen stoppt bei einem Zeilenvorschub, bei EOF oder wenn size Zeichen gelesen wurden, was auch immer zuerst eintritt.


    EDIT: Beachte auch meine Ergänzung oben ;)

  • fgets liest immernoch nur die ersten BUFSIZ Zeichen, also hab ich deinen Vorschlag mal probiert:



    Da die Mail-Queue meist leer ist sollte rauskommen

    Code
    Length=...
    ->Mail queue is empty<-

    tatsächlich erhalte ich

    Code
    Length=1
    ->Mail4queue is empty
    <-


    Der Zeilensprung ist tatsächlich in der Ausgabe enthalten! Irgendeine Idee was das soll? Im übrigen erhalte ich beim zweiten Schleifendurchlauf (da state nie >1 wird) einen Speicherzugriffsfehler. Warum?


    Joe

    Einmal editiert, zuletzt von mrjoe ()

  • Getline verstaut den gelesenen Zeilenwechsel in den Puffer - wenn Du ihn nicht haben willst musst Du das letzte Zeichen löschen.


    Und du _musst_ buffer und len anfangs mit 0 initialisieren, wie im Beispiel gezeigt, weil sonst getline u.U. versucht, nicht vorhandenen Speicher freizugeben. Um genau zu sein allokiert getline einen neuen Puffer, wenn der bestehende nicht ausreicht um die Zeile zu fassen (oder noch keiner vorhanden ist -> 0), und packt dessen Adresse in buffer und die Länge in len. Beim nächsten Mal versucht er den buffer in der Länge wiederzuverwenden, reicht das nicht gibt er ihn frei und schreibt die Adresse eines neuen Puffers samt Länge in buffer und len. Deshalb musst Du ganz zum Schluss diesen auch mit free abräumen.

Jetzt mitmachen!

Sie haben noch kein Benutzerkonto auf unserer Seite? Registrieren Sie sich kostenlos und nehmen Sie an unserer Community teil!