我有一个输出游戏所需文件列表的实用工具。我如何在C程序中运行该实用程序并获取其输出,以便我可以在同一个程序中对其执行操作?如何从C运行外部程序并解析其输出?
更新:良好的信息缺乏通话。该实用程序吐出一系列字符串,并且这应该是Mac/Windows/Linux中完全可移植的。请注意,我正在寻找一种编程方式来执行该实用程序并保留它的输出(转到stdout)。
我有一个输出游戏所需文件列表的实用工具。我如何在C程序中运行该实用程序并获取其输出,以便我可以在同一个程序中对其执行操作?如何从C运行外部程序并解析其输出?
更新:良好的信息缺乏通话。该实用程序吐出一系列字符串,并且这应该是Mac/Windows/Linux中完全可移植的。请注意,我正在寻找一种编程方式来执行该实用程序并保留它的输出(转到stdout)。
对于Unix的十岁上下的环境中的简单问题尝试popen()
。
从手册页:
的POPEN()函数创建一个管道,分叉和调用外壳打开一个过程。
如果您使用读取模式,这正是您所要求的。我不知道它是否在Windows中实现。
对于更复杂的问题,您希望查找进程间通信。
如何正确使用`popen()`的一些例子会很好。 – 2013-07-29 19:29:49
好吧,假设你是在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,popen()
真的是你最好的选择,因为dmckee指出,因为这两个操作系统都支持这一呼吁。在Windows中,这应该帮助:http://msdn.microsoft.com/en-us/library/ms682499.aspx
MSDN文档说 如果在Windows程序中使用_popen函数将返回一个无效的文件指针,导致程序无限期地停止响应。 _popen在控制台应用程序中正常工作。要创建重定向输入和输出的Windows应用程序,请参阅在Windows SDK中使用重定向输入和输出创建子进程。
//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;
}
您可以使用system()
为:
system("ls song > song.txt");
其中ls
是命令名称列出文件夹的歌曲的内容和song
是在当前目录中的文件夹。生成的文件song.txt
将在当前目录中创建。
正如其他人所指出的,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;
}
也看到http://stackoverflow.com/questions/125828/capturing-stdout-from-a-system-command-optimally – rogerdpack 2012-09-25 22:30:32
如果你想要stderr以及你可以重定向,例如调用ls nonexistant-name 2>&1 – Vic 2013-04-10 03:11:25
这不是重复的;链接的问题是** C++特定的**,而这个问题是关于** C **的。 – 2016-03-22 22:21:33