我有一个实用程序,可以输出游戏所需的文件列表。 如何在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;
} |