2008-09-04 39 views
44

我有一個輸出遊戲所需文件列表的實用工具。我如何在C程序中運行該實用程序並獲取其輸出,以便我可以在同一個程序中對其執行操作?如何從C運行外部程序並解析其輸出?

更新:良好的信息缺乏通話。該實用程序吐出一系列字符串,並且這應該是Mac/Windows/Linux中完全可移植的。請注意,我正在尋找一種編程方式來執行該實用程序並保留它的輸出(轉到stdout)。

+0

也看到http://stackoverflow.com/questions/125828/capturing-stdout-from-a-system-command-optimally – rogerdpack 2012-09-25 22:30:32

+0

如果你想要stderr以及你可以重定向,例如調用ls nonexistant-name 2>&1 – Vic 2013-04-10 03:11:25

+5

這不是重複的;鏈接的問題是** C++特定的**,而這個問題是關於** C **的。 – 2016-03-22 22:21:33

回答

45

對於Unix的十歲上下的環境中的簡單問題嘗試popen()

從手冊頁:

的POPEN()函數創建一個管道,分叉和調用外殼打開一個過程。

如果您使用讀取模式,這正是您所要求的。我不知道它是否在Windows中實現。

對於更復雜的問題,您希望查找進程間通信。

+20

如何正確使用`popen()`的一些例子會很好。 – 2013-07-29 19:29:49

7

好吧,假設你是在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上運行,但我從來沒有使用過。

2

MSDN文檔說 如果在Windows程序中使用_popen函數將返回一個無效的文件指針,導致程序無限期地停止響應。 _popen在控制檯應用程序中正常工作。要創建重定向輸入和輸出的Windows應用程序,請參閱在Windows SDK中使用重定向輸入和輸出創建子進程。

0
//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; 
} 
1

您可以使用system()爲:

system("ls song > song.txt"); 

其中ls是命令名稱列出文件夾的歌曲的內容和song是在當前目錄中的文件夾。生成的文件song.txt將在當前目錄中創建。

29

正如其他人所指出的,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; 
} 
相關問題