我有一個輸出遊戲所需文件列表的實用工具。我如何在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