It's often useful to use logging messages or error messages in case something abnormal happens. Or just for fun. A useful trick is to send them straight to the visual studio output window. Using a small amount of code we can even override std::cout and std::cerr which is pretty cool. I'm just going to dive straight into some code:
class logbuf : public std::streambuf
{
public:
virtual std::streamsize xsputn( const char *s, std::streamsize n )
{
// Output to visual studio output window
OutputDebugStringW(widen(s).c_str());
return n;
}
virtual int overflow(int c = EOF)
{
if(c != EOF) OutputDebugString(widen(std::string(1, c)).c_str());
return 1;
}
private:
int indent_;
char last_;
};
int main(int argc, const char* argv[])
{
// Create the new stream to redirect cout and cerr output to vs.
logbuf merr;
std::ostream out(&merr);
// Smart class that will swap streambufs and replace them
// when object goes out of scope.
class StreamBuf_Swapper
{
public:
StreamBuf_Swapper( std::ostream& orig, std::ostream& replacement )
: buf_(orig.rdbuf()), str_(orig)
{ orig.rdbuf( replacement.rdbuf() ); }
~StreamBuf_Swapper() { str_.rdbuf( buf_ ); }
private:
std::streambuf* buf_;
std::ostream& str_;
} cerrswap(std::cerr, out), coutswap(std::cout, out);
try
{
// ... Lots of code
}
catch( const std::exception& e )
{
std::cerr << e.what();
}
return 0;
}
This code takes the streambuf associated with cout and cerr and simply swaps it with a streambuf derived class (vsstream) that prints anything to the visual studio output window. Simple and useful. One other thing to note is that if the output window contains a line formatted:
<filename>(<line number>) : <message>
then it will automatically display that file and line in the editor when double clicked. A few more things you could do with it would be to log errors to a file as well or maybe have something differentiate between normal log messages and error messages (in fact, I'll probably have to do this at some point).
No comments:
Post a Comment