我怎样才能从C运行一个外部程序,并解析其输出?
我有一个输出游戏所需文件列表的实用程序。 我如何在C程序中运行该实用程序并获取其输出,以便在同一个程序中执行该实用程序?
更新:好信息缺乏。 该实用程序吐出一系列的字符串,这应该是完全可移植的跨Mac / Windows / Linux的。 请注意,我正在寻找一个编程方式来执行该实用程序,并保留其输出(这转到标准输出)。
对于Unix-ish环境中的简单问题,请尝试popen()
。
从手册页:
popen()函数通过创建管道,分叉和调用shell来打开一个进程。
如果你使用阅读模式,这正是你所要求的。 我不知道它是否在Windows中实现。
对于更复杂的问题,您要查找进程间通信。
正如其他人指出的, 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; }
在Windows上支持popen,请看这里:
http://msdn.microsoft.com/en-us/library/96ayss4b.aspx
如果你想要它是跨平台的,popen是要走的路。
那么,假设你在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\Temp
,或者C:\Documents and Settings\username\Local Settings\Temp in 2K/XP
。 我认为/tmp
将在OSX中工作,但我从来没有使用过。
在Linux和OS X中,像dmckee指出的那样, popen()
真的是最好的选择,因为两个操作系统都支持这个调用。 在Windows中,这应该有所帮助: http : //msdn.microsoft.com/en-us/library/ms682499.aspx
MSDN文档说如果在Windows程序中使用,_popen函数返回一个无效的文件指针,导致程序无限期地停止响应。 _popen在控制台应用程序中正常工作。 要创建重定向输入和输出的Windows应用程序,请参阅在Windows SDK中使用重定向输入和输出创建子进程。
你可以使用system()
如下所示:
system("ls song > song.txt");
其中ls
是列出文件夹歌曲内容的命令名称, song
是当前目录中的文件夹。 生成的文件song.txt
将在当前目录中创建。
//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; }