我有一个实用程序,可以输出游戏所需的文件列表。如何在 C 程序中运行该实用程序并获取它的输出,以便我可以在同一个程序中对其进行操作?
更新:很好地呼吁缺乏信息。该实用程序会输出一系列字符串,这应该可以跨 Mac/Windows/Linux 移植。请注意,我正在寻找一种编程方式来执行该实用程序并保留其输出(进入标准输出)。
我有一个实用程序,可以输出游戏所需的文件列表。如何在 C 程序中运行该实用程序并获取它的输出,以便我可以在同一个程序中对其进行操作?
更新:很好地呼吁缺乏信息。该实用程序会输出一系列字符串,这应该可以跨 Mac/Windows/Linux 移植。请注意,我正在寻找一种编程方式来执行该实用程序并保留其输出(进入标准输出)。
正如其他人指出的那样,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;
}
样本输出:
OUTPUT: total 16
OUTPUT: -rwxr-xr-x 1 14077 14077 8832 Oct 19 04:32 a.out
OUTPUT: -rw-r--r-- 1 14077 14077 1549 Oct 19 04:32 main.c
对于 Unix-ish 环境中的简单问题,请尝试popen()
.
从手册页:
popen() 函数通过创建管道、分叉和调用 shell 来打开一个进程。
如果您使用阅读模式,这正是您所要求的。我不知道它是否在Windows中实现。
对于更复杂的问题,您需要查找进程间通信。
在 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 放在同一目录中。您可能想研究/tmp
在 nix、C:\Users\username\Local Settings\Temp
Vista 或C:\Documents and Settings\username\Local Settings\Temp in 2K/XP
. 我认为这/tmp
将在 OSX 中工作,但我从未使用过。
popen()
正如 dmckee 指出的那样,在 Linux 和 OS X 中,这确实是您最好的选择,因为这两个操作系统都支持该调用。在 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;
}