2012-06-07 46 views
3

我正在編寫單元測試,因此無法更改我正在測試的文件中的代碼。我正在測試的代碼中包含cout中的消息,我試圖將其重定向到一個文件中,以檢查該程序是否正在輸出正確的消息。有沒有人有辦法將stdout重定向到另一個不會造成延遲的程序?我試過freopen(),並導致我的程序因某種原因掛起。從C++中的另一個程序重定向stdout

+1

這可能是有點OS特定.. –

+0

考慮[這裏](http://stackoverflow.com/questions/3661106/overlapped-readfileex-on-child-process-redirected-stdout-never-fires )。絕對不是一個愚蠢的,但相關的。可能有幫助。 –

+0

此問題已答覆[這裏](http://stackoverflow.com/questions/5257509/freopen-equivalent-for-c-streams)。 – jxh

回答

2

您可以創建一個filebuf然後更換cout的流緩衝吧:

{ 
    std::filebuf f; 
    f.open("output.txt", std::ios::out); 
    std::streambuf* o = std::cout.rdbuf(&f); 
    std::cout << "hello" << std::endl; // endl will flush the stream 
    std::cout.rdbuf(o); 
} 

您需要恢復cout「再次的原始流緩衝(或將其設置爲空指針),或者它可能會在崩潰全球流被刷新並銷燬,因爲filebuf已經超出範圍。

+0

'.rdbuf(0)'打算成爲'.rdbuf(o)'? – ildjarn

+0

可以工作,但是,是的,它的意思是。 –

+0

這導致它以某種方式再次開始掛起。有什麼你知道的,導致它不掛? –

1

您可以使用'open()'和'dup2()'。你可以使用下面提供的助手。如何使用它們的例子:

void 
code_to_test() 
{ 
    std::cout << "Here we go" << std::endl; 
    std::cerr << "Danger danger" << std::endl; 
} 

run_test(code_to_test); 

run_test幫手調用重定向,並運行測試代碼。

template <typename TEST> void 
run_test (TEST t, bool append = false) { 
    flush_output(); 
    Redirect o(1, "/tmp/test_stdout", append); 
    Redirect e(2, "/tmp/test_stderr", append); 
    t(); 
    flush_output(); 
} 

flush_output幫助器刷新流。

void flush_output() { 
    fflush(stdout); 
    fflush(stderr); 
    std::cout.flush(); 
    std::cerr.flush(); 
} 

Redirect類在構造函數中影響重定向。它將原始描述符恢復到析構函數中。

class Redirect 
{ 
    int m_what; 
    int m_old_what; 
public: 
    Redirect (int what, std::string where, bool append = false) 
     : m_what(what), m_old_what(dup(what)) { 
     int flags = O_CREAT|O_WRONLY; 
     if (append) flags |= O_APPEND; 
     int f = open(where.c_str(), flags, 0660); 
     dup2(f, m_what); 
     close(f); 
    } 
    ~Redirect() { 
     dup2(m_old_what, m_what); 
     close(m_old_what); 
    } 
}; 
相關問題