2013-01-11 107 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。 –

相关问题