首页 文章

如何从C运行外部程序并解析其输出?

提问于
浏览
49

我有一个实用程序可以输出游戏所需的文件列表 . 如何在C程序中运行该实用程序并获取其输出,以便我可以在同一程序中对其执行操作?

更新:对缺乏信息的良好呼吁 . 该实用程序吐出一系列字符串,这应该是完全可移植的Mac / Windows / Linux . 请注意,我正在寻找一种程序化的方法来执行该实用程序并保留其输出(转到stdout) .

8 回答

  • 1

    MSDN文档说如果在Windows程序中使用,_popen函数返回一个无效的文件指针,导致程序无限期地停止响应 . _popen在控制台应用程序中正常工作 . 要创建重定向输入和输出的Windows应用程序,请参阅在Windows SDK中创建具有重定向输入和输出的子进程 .

  • 7
    //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;
    }
    
  • 2

    在Linux和OS X中,正如dmckee指出的那样, popen() 确实是你最好的选择,因为两个操作系统都支持该调用 . 在Windows中,这应该有所帮助:http://msdn.microsoft.com/en-us/library/ms682499.aspx

  • 49

    Windows支持popen,请看:

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

    如果您希望它是跨平台的,那么popen就是您的选择 .

  • -1

    您可以使用 system() ,如下所示:

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

    其中 ls 是列出文件夹歌曲内容的命令名称, song 是当前目录中的文件夹 . 生成的文件 song.txt 将在当前目录中创建 .

  • 3

    正如其他人所指出的那样, popen() 是最标准的方式 . 由于没有回答提供了使用此方法的示例,因此在这里:

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

    好吧,假设您在Windows环境中使用命令行,则可以使用管道或命令行重定向 . 例如,

    commandThatOutputs.exe > someFileToStoreResults.txt
    

    要么

    commandThatOutputs.exe | yourProgramToProcessInput.exe
    

    在程序中,您可以使用C标准输入函数来读取其他程序输出(scanf等):http://irc.essex.ac.uk/www.iota-six.co.uk/c/c1_standard_input_and_output.asp . 您也可以使用文件示例并使用fscanf . 这也适用于Unix / Linux .

    这是一个非常通用的问题,您可能希望包含更多详细信息,例如它的输出类型(只是文本或二进制文件?)以及您希望如何处理它 .

    编辑:万岁澄清!

    重定向STDOUT看起来很麻烦,我不得不在.NET中做到这一点,它给了我各种令人头疼的问题 . 看起来正确的C方式是生成一个子进程,获取一个文件指针,突然我的头疼 .

    所以这是一个使用临时文件的黑客 . 这很简单,但它应该有效 . 如果速度不是问题(击中磁盘很慢),或者它是丢失的话,这将很有效 . 如果您正在构建企业程序,那么使用其他人推荐的方法查看STDOUT重定向可能是最好的 .

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

    确保检查你的文件权限:现在这只是将文件放在与exe相同的目录中 . 您可能希望在nix中使用 /tmp ,或在Vista中使用 C:\Users\username\Local Settings\TempC:\Documents and Settings\username\Local Settings\Temp in 2K/XP . 我认为 /tmp 将在OSX中运行,但我从未使用过 .

  • 44

    对于Unix-ish环境中的简单问题,请尝试popen() .

    从手册页:

    popen()函数通过创建管道,分叉和调用shell来打开一个进程 .

    如果您使用读取模式,这正是您要求的 . 我不知道它是否在Windows中实现 .

    对于更复杂的问题,您希望查找进程间通信 .

相关问题