2013-01-11 144 views
2

將cout或cerr重定向到文件很容易。我可以使用它將第三方輸出重定向到一個文件。但是,在將第三方輸出重定向到文件之後,我如何使用cout自己輸出到控制檯?將cout或cerr重定向到文件後使用cout或cerr輸出到控制檯

+4

什麼是 「第三者輸出」? –

+0

通常從代碼中的另一個團隊調試喋喋不休的人寫道。我想我可以戳他們給我一個接口,讓他們輸出到別的地方。但我想知道是否有另一種方法可以解決這個問題,以防我進入一種我無法影響被調用代碼的情況。 – inetknght

回答

4

我RAII的忠實球迷,所以我曾寫了這個小助手類。它將重定向流直到它超出範圍,此時它會恢復原始緩衝區。非常方便。 :)

class StreamRedirector { 
public: 
    explicit StreamRedirector(std::ios& stream, std::streambuf* newBuf) : 
     savedBuf_(stream.rdbuf()), stream_(stream) 
    { 
     stream_.rdbuf(newBuf); 
    } 

    ~StreamRedirector() { 
     stream_.rdbuf(savedBuf_); 
    } 

private: 
    std::streambuf* savedBuf_; 
    std::ios& stream_; 
}; 

可以使用這樣的:

using namespace std; 
cout << "Hello stdout" << endl; 
{ 
    ofstream logFile("log.txt"); 
    StreamRedirector redirect(cout, logFile.rdbuf()); 
    cout << "In log file" << endl; 
} 
cout << "Back to stdout" << endl; 
+0

我喜歡使用匿名範圍來處理它。我已經將其用於其他RAII對象。除了一個更好的解決方案,我會說這將不得不做。它仍然不能解決其他線程的使用,特別是如果這些線程沒有同步機制的話。 – inetknght

+0

那麼,只要其他線程不改變任何'rdbuf',並且在調用任何可能的線程產生庫之前執行重定向,那麼應該沒有問題,我想呢?除非我錯過了這裏的東西.. –

+0

我認爲這將取決於實施。我不知道一個線程在線程產生時會獲得它自己的cout狀態副本的保證嗎? – inetknght

4

您保存緩衝並在以後恢復它:

std::streambuf *buf = std::cout.rdbuf(); //save 
// Do other stuff 
std::cout.rdbuf(buf); // restore 
+0

如果第三方庫有其他線程調用cout會怎麼樣? – inetknght

+1

@inetknght:[查看此SO問題](http://stackoverflow.com/questions/6374264/is-cout-synchronized-thread-safe)瞭解有關C++ 03和C++ 11之間差異的更多信息,但基本上你必須自己管理同步,並確保多個線程不同時寫入cout。 –

相關問題