Pregunta

Tengo una utilidad que genera una lista de archivos necesarios para un juego.¿Cómo puedo ejecutar esa utilidad dentro de un programa C y obtener su resultado para poder actuar dentro del mismo programa?

ACTUALIZAR:Buena decisión ante la falta de información.La utilidad escupe una serie de cadenas y se supone que es completamente portátil en Mac/Windows/Linux.Tenga en cuenta que estoy buscando una forma programática de ejecutar la utilidad y conservar su salida (que va a la salida estándar).

¿Fue útil?

Solución

Para problemas simples en entornos Unix, intente popen().

Desde la página de manual:

La función popen() abre un proceso creando una tubería, bifurcando e invocando el shell.

Si utiliza el modo de lectura, esto es exactamente lo que solicitó.No sé si está implementado en Windows.

Para problemas más complicados, desea buscar comunicación entre procesos.

Otros consejos

Como otros han señalado, popen() es la forma más estándar.Y como ninguna respuesta proporcionó un ejemplo usando este método, aquí va:

#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 es compatible con Windows, consulte aquí:

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

Si quieres que sea multiplataforma, popen es el camino a seguir.

Bueno, asumiendo que estás en una línea de comando en un entorno Windows, puedes usar canalizaciones o redireccionamientos de línea de comando.Por ejemplo,

commandThatOutputs.exe > someFileToStoreResults.txt

o

commandThatOutputs.exe | yourProgramToProcessInput.exe

Dentro de su programa, puede usar las funciones de entrada estándar de C para leer la salida de otros programas (scanf, etc.): http://irc.essex.ac.uk/www.iota-six.co.uk/c/c1_standard_input_and_output.asp .También puedes usar el archivo de ejemplo y usar fscanf.Esto también debería funcionar en Unix/Linux.

Esta es una pregunta muy genérica; es posible que desees incluir más detalles, como qué tipo de salida es (¿solo texto o un archivo binario?) y cómo deseas procesarlo.

Editar:¡Hurra aclaración!

Redirigir STDOUT parece problemático, tuve que hacerlo en .NET y me dio todo tipo de dolores de cabeza.Parece que la forma correcta de C es generar un proceso hijo, obtener un puntero de archivo y, de repente, me duele la cabeza.

Aquí tienes un truco que utiliza archivos temporales.Es simple, pero debería funcionar.Esto funcionará bien si la velocidad no es un problema (golpear el disco es lento) o si es desechable.Si está creando un programa empresarial, probablemente sea mejor buscar en la redirección STDOUT, utilizando lo que otras personas recomendaron.

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

Asegúrese de verificar los permisos de sus archivos:En este momento, esto simplemente colocará el archivo en el mismo directorio que un exe.Es posible que desee considerar el uso /tmp en nada, o C:\Users\username\Local Settings\Temp en Vista, o C:\Documents and Settings\username\Local Settings\Temp in 2K/XP.Pienso que el /tmp Funcionará en OSX, pero nunca he usado uno.

En Linux y OS X, popen() Realmente es su mejor opción, como señaló dmckee, ya que ambos sistemas operativos admiten esa llamada.En Windows, esto debería ayudar: http://msdn.microsoft.com/en-us/library/ms682499.aspx

La documentación de MSDN dice que si se usa en un programa de Windows, la función _popen devuelve un puntero de archivo no válido que hace que el programa deje de responder indefinidamente._popen funciona correctamente en una aplicación de consola.Para crear una aplicación de Windows que redirija la entrada y la salida, consulte Creación de un proceso secundario con entrada y salida redirigidas en el SDK de Windows.

Puedes usar system() como en:

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

dónde ls es el nombre del comando para enumerar el contenido de la carpeta canción y song es una carpeta en el directorio actual.archivo resultante song.txt se creará en el directorio actual.

//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;
}
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top