2013-08-06 111 views
6

我想做重定向標準輸出/標準錯誤到UNIX下的C++文件 - 再次

重定向輸出和錯誤從內C++

到一個或多個文件是什麼,爲什麼我需要它

我正在使用一個外部的,預編譯的第三方庫,產生一個荒謬的輸出量,我想重定向到一個日誌文件以保持控制檯清潔。

條件

兼容性是沒有問題的,代碼將只在Unix系統上運行。重定向不僅應該影響C++樣式的打印(std :: cout < <「hello world」< < std :: endl),還要打印c樣式(printf(「hello world \ n」))。

我已經試過到目前爲止

我一直在計算器上瀏覽了半天,讀取多個答案具有類似問題的人。有了這些答案的幫助下,我已經能夠總結了以下的一段代碼:


#include <stdio.h> 
#include <iostream> 
#include <fcntl.h> 
#include "unistd.h" 

const int stdoutfd(dup(fileno(stdout))); 

int redirect_stdout(const char* fname){ 
    fflush(stdout); 
    int newstdout = open(fname, O_WRONLY | O_CREAT, S_IRUSR | S_IWUSR | S_IRGRP |  S_IROTH); 
    dup2(newstdout, fileno(stdout)); 
    close(newstdout); 
} 

int restore_stdout(){ 
    fflush(stdout); 
    dup2(stdoutfd, fileno(stdout)); 
    close(stdoutfd); 
    return stdoutfd; 
} 

int main(){ 
    redirect_stdout("/dev/null"); 
    std::cout << "invisible 1" << std::endl; 
    restore_stdout(); 
    std::cout << "visible 1" << std::endl; 
    redirect_stdout("/dev/null"); 
    std::cout << "invisible 2" << std::endl; 
    restore_stdout(); 
    std::cout << "visible 2" << std::endl; 
    return 0; 
} 

我希望看到:

visible 1 
visible 2 

我其實見

visible 1 

也就是說,當使用這個機制第一次,它的工作原理 - 但如果再次使用,恢復輸出將無法正常工作。 有人可以指出我需要改變什麼以使機制無限地工作嗎?

+0

可能重複:http://stackoverflow.com/questions/4810516/c-redirecting-stdout – Kelm

回答

4

如果你想重複使用它,請不要在restore_stdout關閉stdoutfd

1

你是正在尋找這樣的事情: -

int main() 
{ 
    // Save original std::cin, std::cout 
    std::streambuf *coutbuf = std::cout.rdbuf(); 
    std::streambuf *cinbuf = std::cin.rdbuf(); 

    std::ofstream out("outfile.txt"); 
    std::ifstream in("infile.txt"); 

    //Read from infile.txt using std::cin 
    std::cin.rdbuf(in.rdbuf()); 

    //Write to outfile.txt through std::cout 
    std::cout.rdbuf(out.rdbuf()); 

    std::string test; 
    std::cin >> test;   //from infile.txt 
    std::cout << test << " "; //to outfile.txt 

    //Restore back. 
    std::cin.rdbuf(cinbuf); 
    std::cout.rdbuf(coutbuf); 

} 

從我前面answer

+1

感謝您的答案 - 但是,我應該說,我想不僅重定向C++ - 樣式的打印語句,還有使用printf的plain-c打印語句 - 您的解決方案無法完成。對於不準確的抱歉,我相應地編輯了這個問題。 – carsten

0

對於C++輸入輸出流,你可以使用rdbuf 非const重載設置std::coutstd::filebuf。 (這最好由 表示RAII類的方法,因爲你必須在 離開main之前恢復它。)對於C FILE*,可以使用freopen,但是 我認爲你不能恢復它。

FWIW:這兩種解決方案都只使用標準C++或C,所以 應該是可移植的。

1

以及我u'd更好地利用freopen函數()

用法語法:

freopen("RedToFile","r",stdout); 
or 
freopen("/dev/null","a",stdout); 

也是如此 「標準錯誤」

0

除了afr0ck答案freopen()我想說的在使用freopen()時,我們應該小心。一旦像stdoutstdin這樣的數據流通過分配新目標(這裏是'output.txt'文件)重新打開,它總是保留爲程序,除非它已被明確更改。

freopen("output.txt", "a", stdout); 

這裏標準輸出流stdout被重新打開,並與分配「output.txt的」文件。之後,無論何時我們使用printf()或任何其他stdout流如 - putchar()那麼每個輸出將轉到'output.txt'。要返回的默認行爲(即打印在控制檯/終端輸出)的printf()putchar()我們可以使用下面的代碼行 -

  • 對GCC,Linux發行版如Ubuntu - freopen("/dev/tty", "w", stdout);
  • (MinGW版本) C/C++,窗戶 - freopen("CON", "w", stdout);

請參見下面的代碼示例 -

#include <stdio.h> 

int main() { 

    printf("No#1. This line goes to terminal/console\n"); 

    freopen("output.txt", "a", stdout); 
    printf("No#2. This line goes to the \"output.txt\" file\n"); 
    printf("No#3. This line aslo goes to the \"output.txt\" file\n"); 

    freopen("/dev/tty", "w", stdout); /*for gcc, diffrent linux distro eg. - ubuntu*/ 
    //freopen("CON", "w", stdout); /*Mingw C++; Windows*/ 
    printf("No#4. This line again goes to terminal/console\n");   

} 

這代碼會在當前目錄中生成一個'output.txt'文件,並且No#2和No#3將被打印在'output.txt'文件中。

感謝

相關問題