Domanda

Ho un'utilità che genera un elenco di file richiesti da un gioco.Come posso eseguire quell'utilità all'interno di un programma C e catturarne l'output in modo da poter agire su di esso all'interno dello stesso programma?

AGGIORNAMENTO:Buona chiamata sulla mancanza di informazioni.L'utilità genera una serie di stringhe e dovrebbe essere completamente portabile su Mac/Windows/Linux.Tieni presente che sto cercando un modo programmatico per eseguire l'utilità e conservarne l'output (che va su stdout).

È stato utile?

Soluzione

Per problemi semplici in ambienti Unix, prova popen().

Dalla pagina man:

La funzione popen() apre un processo creando una pipe, biforcandosi e invocando la shell.

Se usi la modalità di lettura questo è esattamente quello che hai chiesto.Non so se è implementato in Windows.

Per problemi più complicati è necessario cercare la comunicazione tra processi.

Altri suggerimenti

Come altri hanno sottolineato, popen() è il modo più standard.E poiché nessuna risposta ha fornito un esempio utilizzando questo metodo, eccolo qui:

#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;
}

popen è supportato su Windows, vedere qui:

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

Se vuoi che sia multipiattaforma, popen è la strada da percorrere.

Bene, supponendo che tu sia su una riga di comando in un ambiente Windows, puoi utilizzare pipe o reindirizzamenti della riga di comando.Ad esempio,

commandThatOutputs.exe > someFileToStoreResults.txt

O

commandThatOutputs.exe | yourProgramToProcessInput.exe

All'interno del tuo programma, potresti utilizzare le funzioni di input standard del C per leggere l'output degli altri programmi (scanf, ecc.): http://irc.essex.ac.uk/www.iota-six.co.uk/c/c1_standard_input_and_output.asp .Potresti anche usare il file example e usare fscanf.Questo dovrebbe funzionare anche in Unix/Linux.

Questa è una domanda molto generica, potresti voler includere maggiori dettagli, ad esempio che tipo di output è (solo testo o un file binario?) e come vuoi elaborarlo.

Modificare:Evviva chiarimenti!

Reindirizzare STDOUT sembra essere problematico, ho dovuto farlo in .NET e mi ha dato ogni sorta di mal di testa.Sembra che il modo C corretto sia generare un processo figlio, ottenere un puntatore a un file e all'improvviso mi fa male la testa.

Quindi ecco un trucco che utilizza file temporanei.È semplice, ma dovrebbe funzionare.Funzionerà bene se la velocità non è un problema (l'accesso al disco è lento) o se è da buttare via.Se stai creando un programma aziendale, probabilmente è meglio esaminare il reindirizzamento STDOUT, utilizzando ciò che altre persone hanno consigliato.

#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.
}

Assicurati di controllare i permessi dei file:in questo momento questo semplicemente getterà il file nella stessa directory di un exe.Potresti voler esaminare l'utilizzo /tmp in nix, o C:\Users\username\Local Settings\Temp in Vista, o C:\Documents and Settings\username\Local Settings\Temp in 2K/XP.Penso che la /tmp funzionerà in OSX, ma non ne ho mai usato uno.

In Linux e OS X, popen() è davvero la soluzione migliore, come ha sottolineato dmckee, poiché entrambi i sistemi operativi supportano quella chiamata.In Windows, questo dovrebbe aiutare: http://msdn.microsoft.com/en-us/library/ms682499.aspx

La documentazione di MSDN afferma che se utilizzata in un programma Windows, la funzione _Popen restituisce un puntatore di file non valido che fa sì che il programma interrompa la risposta indefinitamente._popen funziona correttamente in un'applicazione console.Per creare un'applicazione Windows che reindirizza input e output, vedere Creazione di un processo figlio con input e output reindirizzati in Windows SDK.

Puoi usare system() come in:

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

Dove ls è il nome del comando per elencare il contenuto della cartella song e song è una cartella nella directory corrente.File risultante song.txt verrà creato nella directory corrente.

//execute external process and read exactly binary or text output
//can read image from Zip file for example
string run(const char* cmd){
    FILE* pipe = popen(cmd, "r");
    if (!pipe) return "ERROR";
    char buffer[262144];
    string data;
    string result;
    int dist=0;
    int size;
    //TIME_START
    while(!feof(pipe)) {
        size=(int)fread(buffer,1,262144, pipe); //cout<<buffer<<" size="<<size<<endl;
        data.resize(data.size()+size);
        memcpy(&data[dist],buffer,size);
        dist+=size;
    }
    //TIME_PRINT_
    pclose(pipe);
    return data;
}
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top