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