Wie kann ich ein externes Programm von C ausführen und seine Ausgabe analysieren?

Lesezeit: 6 Minuten

Benutzeravatar von Josh Matthews
Josh Matthews

Ich habe ein Dienstprogramm, das eine Liste von Dateien ausgibt, die von einem Spiel benötigt werden. Wie kann ich dieses Dienstprogramm in einem C-Programm ausführen und seine Ausgabe abrufen, damit ich im selben Programm darauf reagieren kann?

UPDATE: Guter Aufruf zum Mangel an Informationen. Das Dienstprogramm spuckt eine Reihe von Zeichenfolgen aus, die auf Mac/Windows/Linux portierbar sein sollen. Bitte beachten Sie, dass ich nach einer programmgesteuerten Möglichkeit suche, das Dienstprogramm auszuführen und seine Ausgabe beizubehalten (die an stdout geht).

  • siehe auch stackoverflow.com/questions/125828/…

    – Rogerpack

    25. September 2012 um 22:30 Uhr

  • Wenn Sie auch stderr wollen, können Sie umleiten, zum Beispiel rufen Sie ls nonexistant-name 2>&1 auf

    – Vic

    10. April 2013 um 3:11 Uhr

  • Dies ist kein Duplikat; Die verknüpfte Frage ist C++ spezifischwährend es bei dieser Frage darum geht C.

    – Kyle Strand

    22. März 2016 um 22:21 Uhr

  • Ich stimme dafür, diese Frage erneut zu öffnen, da es sich nicht um ein Duplikat handelt, sondern um C, nicht um C ++

    – hasan

    20. Juni 2017 um 9:51 Uhr

  • siehe auch stackoverflow.com/questions/9405985/…

    – Munition Göttsch

    3. September 2017 um 15:37 Uhr

Benutzeravatar von MestreLion
MestreLion

Wie andere bereits betont haben, popen() ist der üblichste Weg. Und da keine Antwort ein Beispiel mit dieser Methode lieferte, hier geht es:

#include <stdio.h>

#define BUFSIZE 128

int parse_output(void) {
    char *cmd = "ls -l";    
    
    char buf[BUFSIZE];
    FILE *fp;

    if ((fp = popen(cmd, "r")) == NULL) {
        printf("Error opening pipe!\n");
        return -1;
    }

    while (fgets(buf, BUFSIZE, fp) != NULL) {
        // Do whatever you want here...
        printf("OUTPUT: %s", buf);
    }

    if (pclose(fp)) {
        printf("Command not found or exited with error status\n");
        return -1;
    }

    return 0;
}

Beispielausgabe:

OUTPUT: total 16
OUTPUT: -rwxr-xr-x 1 14077 14077 8832 Oct 19 04:32 a.out
OUTPUT: -rw-r--r-- 1 14077 14077 1549 Oct 19 04:32 main.c

  • Sollte nicht if(pclose(fp)) sein if(pclose(fp) == -1)?

    – Spikatrix

    31. März 2016 um 9:03 Uhr

  • @CoolGuy: hängt davon ab, was Sie wollen. pclose() Rückkehr -1 wenn beim Abrufen des Exit-Status des Befehls ein Fehler aufgetreten ist, ansonsten wird der Exit-Status selbst zurückgegeben. Als Befehle setzen Sie traditionell den Exit-Status 0 um Erfolg anzuzeigen, durch Ankreuzen if(pclose(fp)) Wir testen beide auf Fehler pclose() oder der Befehl.

    – MestreLion

    31. März 2016 um 22:48 Uhr

  • Vielen Dank für dieses Beispiel, es leitet die Ausgabe eines anderen Programms an die Ausgabe des aktuellen Programms weiter. Vielen Dank!

    – Jo

    30. März 2019 um 0:20 Uhr

  • Ein weiteres Beispiel: Gibt es eine Möglichkeit, die Ausgabe eines Linux-Befehls (wie ifconfig) in einer .txt-Datei mit einem C-Programm zu erhalten?

    – Gabriel Staples

    9. Dezember 2021 um 6:31 Uhr


  • @GabrielStaples: fgets() eignet sich eher zum Lesen von Textausgaben als von binären, da es automatisch eine Zeile nach der anderen abruft und bei Zeilenumbrüchen aufteilt. Beides erfordert die while Schleife, da Sie nicht sicher sein können, dass die gesamte Ausgabe hineinpasst BUFSIZE.

    – MestreLion

    9. Dezember 2021 um 19:51 Uhr


dmckee --- Benutzeravatar des Ex-Moderators Kitten
dmckee — Ex-Moderator-Kätzchen

Bei einfachen Problemen in Unix-ähnlichen Umgebungen versuchen Sie es popen().

Aus der Manpage:

Die Funktion popen() öffnet einen Prozess, indem sie eine Pipe erstellt, die Shell verzweigt und aufruft.

Wenn Sie den Lesemodus verwenden, ist dies genau das, wonach Sie gefragt haben. Ich weiß nicht, ob es in Windows implementiert ist.

Für kompliziertere Probleme sollten Sie die Kommunikation zwischen Prozessen nachschlagen.

  • einige Beispiele für die richtige Verwendung popen() wäre nett.

    – Alexej Magura

    29. Juli 2013 um 19:29 Uhr

  • Ich habe einen Link zur Manpage Open Group für die Funktion hinzugefügt, der ein Beispiel enthält. Grundsätzlich popen bekommt man einen Dateizeiger sehr ähnlich fopen. Es ist nur so, dass Sie damit in die Standardeingabe schreiben oder von der Standardausgabe eines Programms lesen können, anstatt mit einer Festplattendatei zu interagieren. Das ist Unix „Alles ist eine Datei“ Philosophie am Werk. Einige Implementierungen erweitern den Standard, indem sie eine bidirektionale Kommunikation ermöglichen.

    – dmckee — Ex-Moderator-Kätzchen

    30. Juli 2013 um 1:09 Uhr

  • Darauf deutet diese Antwort hin popen ist unter Windows verfügbar.

    – Jonathon Reinhart

    25. Juni 2015 um 19:17 Uhr

  • Für die Lösung mit den Raw-Dateihandles (wenn Sie zum Beispiel asynchrone E/A benötigen) siehe stackoverflow.com/questions/9405985/…

    – Munition Göttsch

    3. September 2017 um 15:36 Uhr

Benutzeravatar von Adam Pierce
Adam Pierc

popen wird unter Windows unterstützt, siehe hier:

http://msdn.microsoft.com/en-us/library/96ayss4b.aspx

Wenn Sie möchten, dass es plattformübergreifend ist, ist Popen der richtige Weg.

Benutzeravatar von David J. Sokol
David J. Sokol

Angenommen, Sie befinden sich auf einer Befehlszeile in einer Windows-Umgebung, können Sie Pipes oder Befehlszeilenumleitungen verwenden. Zum Beispiel,

commandThatOutputs.exe > someFileToStoreResults.txt

oder

commandThatOutputs.exe | yourProgramToProcessInput.exe

Innerhalb Ihres Programms könnten Sie die C-Standardeingabefunktionen verwenden, um die Ausgabe anderer Programme zu lesen (scanf usw.): http://irc.essex.ac.uk/www.iota-six.co.uk/c/c1_standard_input_and_output.asp . Sie könnten auch das Dateibeispiel verwenden und fscanf verwenden. Dies sollte auch unter Unix/Linux funktionieren.

Dies ist eine sehr allgemeine Frage. Vielleicht möchten Sie weitere Details angeben, z. B. um welche Art von Ausgabe es sich handelt (nur Text oder eine Binärdatei?) Und wie Sie sie verarbeiten möchten.

Edit: Hurra Klarstellung!

Das Umleiten von STDOUT scheint mühsam zu sein, ich musste es in .NET tun, und es hat mir alle möglichen Kopfschmerzen bereitet. Es sieht so aus, als ob der richtige C-Weg darin besteht, einen untergeordneten Prozess zu erzeugen, einen Dateizeiger zu erhalten, und plötzlich tut mir der Kopf weh.

Hier ist also ein Hack, der temporäre Dateien verwendet. Es ist einfach, aber es sollte funktionieren. Dies funktioniert gut, wenn die Geschwindigkeit kein Problem darstellt (das Auftreffen auf die Festplatte ist langsam) oder wenn es weggeworfen wird. Wenn Sie ein Unternehmensprogramm erstellen, ist es wahrscheinlich am besten, sich die STDOUT-Umleitung anzusehen und zu verwenden, was andere Leute empfohlen haben.

#include <stdlib.h>
#include <stdio.h>

int main(int argc, char* argv[])
{
    FILE * fptr;                    // file holder
    char c;                         // char buffer


    system("dir >> temp.txt");      // call dir and put it's contents in a temp using redirects.
    fptr = fopen("temp.txt", "r");  // open said file for reading.
                                    // oh, and check for fptr being NULL.
    while(1){
        c = fgetc(fptr);
        if(c!= EOF)
            printf("%c", c);        // do what you need to.
        else
            break;                  // exit when you hit the end of the file.
    }
    fclose(fptr);                   // don't call this is fptr is NULL.  
    remove("temp.txt");             // clean up

    getchar();                      // stop so I can see if it worked.
}

Stellen Sie sicher, dass Sie Ihre Dateiberechtigungen überprüfen: Im Moment wird die Datei einfach in dasselbe Verzeichnis wie eine EXE-Datei geworfen. Vielleicht möchten Sie sich mit der Verwendung befassen /tmp in nix, bzw C:\Users\username\Local Settings\Temp unter Vista, bzw C:\Documents and Settings\username\Local Settings\Temp in 2K/XP. Ich denke, die /tmp wird in OSX funktionieren, aber ich habe noch nie einen verwendet.

Unter Linux und OS X, popen() ist wirklich die beste Wahl, wie dmckee betonte, da beide Betriebssysteme diesen Aufruf unterstützen. Unter Windows sollte das helfen: http://msdn.microsoft.com/en-us/library/ms682499.aspx

Benutzeravatar von Angus Connell
Angus Conell

Laut MSDN-Dokumentation gibt die _popen-Funktion bei Verwendung in einem Windows-Programm einen ungültigen Dateizeiger zurück, der dazu führt, dass das Programm auf unbestimmte Zeit nicht mehr reagiert. _popen funktioniert ordnungsgemäß in einer Konsolenanwendung. Informationen zum Erstellen einer Windows-Anwendung, die Eingabe und Ausgabe umleitet, finden Sie unter Erstellen eines untergeordneten Prozesses mit umgeleiteter Eingabe und Ausgabe im Windows SDK.

Benutzeravatar von JB
JB.

Sie können verwenden system() wie in:

system("ls song > song.txt");

wo ls ist der Befehlsname zum Auflisten des Inhalts des Ordners song und song ist ein Ordner im aktuellen Verzeichnis. Resultierende Datei song.txt wird im aktuellen Verzeichnis erstellt.

  • Was ist, wenn ich die Ausgabe anderer Programme in eine Datei umleiten möchte? kein os-Befehl

    – Amin Da.

    17. April 2016 um 1:30 Uhr

  • Nein, das ist ein sehr schlechter Weg. Machen Sie es richtig mit Pipes, hinterlassen Sie keine temporären Dateien im gesamten Dateisystem.

    – Eule

    5. Oktober 2018 um 14:55 Uhr

1418510cookie-checkWie kann ich ein externes Programm von C ausführen und seine Ausgabe analysieren?

This website is using cookies to improve the user-friendliness. You agree by using the website further.

Privacy policy