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

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

How can I run an external program from C and parse its output?

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

更新:很好的呼吁缺乏信息。 该实用程序会发出一系列字符串,并且应该可以在Mac / Windows / Linux上完全移植。 请注意,我正在寻找一种编程方式来执行该实用程序并保留其输出(将其输出到stdout)。


正如其他人指出的那样,popen()是最标准的方法。由于没有答案提供了使用此方法的示例,因此请按以下步骤进行:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
#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!
"
);
        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
"
);
        return -1;
    }

    return 0;
}

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

从手册页:

The popen() function opens a process by creating a pipe, forking and invoking the shell.

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

对于更复杂的问题,您需要查找进程间通信。


Windows上支持popen,请参见此处:

http://msdn.microsoft.com/zh-CN/library/96ayss4b.aspx

如果您希望它是跨平台的,则应该使用popen。


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

1
commandThatOutputs.exe > someFileToStoreResults.txt

要么

1
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重定向。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
#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\Temp,或C:\Documents and Settings\username\Local Settings\Temp in 2K/XP。我认为/tmp可以在OSX中使用,但是我从未使用过。


正如dmckee所指出的,在Linux和OS X中,popen()确实是最好的选择,因为这两个OS都支持该调用。在Windows中,这应该会有所帮助:http://msdn.microsoft.com/zh-cn/library/ms682499.aspx


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


您可以按以下方式使用system()

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

其中ls是用于列出文件夹歌曲内容的命令名称,而song是当前目录中的文件夹。结果文件song.txt将在当前目录中创建。


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
//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;
}

推荐阅读

    linux自动运行命令?

    linux自动运行命令?,服务,系统,时间,代码,周期性,第一,命令,管理,在线,状态,l

    linux开启运行命令?

    linux开启运行命令?,系统,服务,工作,管理,状态,命令,标准,情况,环境,工具,lin

    linux运行wps命令?

    linux运行wps命令?,软件,官网,名称,时间,电脑,系统,工具,环境,项目,数据,wps

    linux命令输出加时间?

    linux命令输出加时间?,时间,系统,名称,设备,命令,信息,管理,标准,数字,百度,l

    linux命令日志输出?

    linux命令日志输出?,系统,状态,命令,情况,对比,标准,实时,服务,下来,数据,怎

    linux运行cmd命令?

    linux运行cmd命令?,电脑,系统,状态,情况,环境,命令,单位,管理,设备,数据,电脑

    linux命令输出到vi?

    linux命令输出到vi?,工作,系统,状态,档案,命令,模式,信息,正规,第一,编辑,lin

    linux命令输出截取?

    linux命令输出截取?,位置,网上,信息,命令,字符串,字符,左边,日志,中间,之间,L

    linux运行两个命令?

    linux运行两个命令?,网络,地址,系统,工作,暂停,命令,网站,密码,网上,入口,Lin

    linux命令输出计算?

    linux命令输出计算?,标准,地址,工作,信息,系统,命令,软件,数据,文件,控制台,l

    linux持续命令输出?

    linux持续命令输出?,系统,工作,地址,信息,情况,状态,数据,管理,工具,指标,lin

    linux命令行打印输出?

    linux命令行打印输出?,地址,工作,命令,网络,信息,标准,系统,文件,目录,控制

    linux命令运行代码?

    linux命令运行代码?,代码,单位,系统,环境,连续,保险,工具,命令,文件,音乐,Lin

    linux命令运行脚本?

    linux命令运行脚本?,代码,系统,工作,设计,状态,命令,脚本,文件,目录,终端,运

    linux上运行的命令?

    linux上运行的命令?,系统,工作,软件,网络,地址,信息,情况,命令,灵活,基础知

    linux怎么运行命令?

    linux怎么运行命令?,系统,工作,首页,工具,终端,地址,命令,信息,电脑,情况,怎

    linux右击运行命令?

    linux右击运行命令?,系统,工作,设备,标准,首页,发行,电脑,终端,命令,文件,lin

    linux如何运行命令?

    linux如何运行命令?,系统,工具,基础,代码,环境,管理,网络,初级,密码,终端,Lin

    linux命令输出最大值?

    linux命令输出最大值?,地址,网络,系统,时间,数据,高位,较大,位置,不了,最大

    linux接收命令运行?

    linux接收命令运行?,系统,工作,工具,信息,地址,命令,连续,代码,管理,发行,lin