Click here to Skip to main content
11,713,845 members (86,289 online)
Click here to Skip to main content

Using an output stream for debugging

, 24 Nov 2001 Public Domain 171.5K 38
Rate this:
Please Sign up or sign in to vote.
How to create an output stream that writes to the debug terminal.

Background

There are many different schools of how to debug a program (yeah, I know - write it correctly from the start), but whatever tools you prefer it is often very convenient just to use the printf approach. Well, since you are a modern C++ kind of person, you don't really want printf, you want to use an output stream, like cerr.

There's just one problem though, you are writing Windows applications, so there is no standard error output to write to. Not true, actually there is, and you've probably used many times already. When you use one of the TRACE macros, the result ends up in the Debug pane of Visual Studio. MFC goes through great pains to turn off all this debug output in Release builds, but it can often be very convenient to keep it.

Of course, you won't see any output in Visual Studio from a release build, but there are other programs that can capture this output. A good one is DebugView from www.sysinternals.com. Incidentially, if you start this program you'll probably see like a million messages from Internet Explorer. There you go, even Microsoft practise Release build debugging!

The problem

So, how to direct a standard output stream to the debug terminal? In general, the correct answer is to derive from streambuf and connect the new class to a normal ostream. In this way all stream inserters and manipulators work as expected. In this case we can save some work by deriving from stringbuf instead. So, without further ado, here's how to do it:

The code

First we include the needed headers.

#include <Windows.h>
#include <ostream>
#include <sstream>
#include <string>

Now for the real work: Since we are using a stringbuf we only need to override the sync function.

The sync method is what actually transfers the text in the put area to whatever output destination the streambuf uses, in this case by calling the API function OutputDebugString.

template <class CharT, class TraitsT = std::char_traits<CharT> >
class basic_debugbuf : 
    public std::basic_stringbuf<CharT, TraitsT>
{
public:

    virtual ~basic_debugbuf()
    {
        sync();
    }

protected:

    int sync()
    {
        output_debug_string(str().c_str());
        str(std::basic_string<CharT>());    // Clear the string buffer

        return 0;
    }

    void output_debug_string(const CharT *text) {}
};

Next, I specialize the output routine so it calls the Ansi or Unicode API as appropriate.

template<>
void basic_debugbuf<char>::output_debug_string(const char *text)
{
    ::OutputDebugStringA(text);
}

template<>
void basic_debugbuf<wchar_t>::output_debug_string(const wchar_t *text)
{
    ::OutputDebugStringW(text);
}

That's really all you need, but as a convenience I also provide a class derived from basic_ostream that connects the output stream to the basic_debugbuf just created.

In order to work just like cout, you should then create a global object of type dostream or wdostream and use that to output to.

template<class CharT, class TraitsT = std::char_traits<CharT> >
class basic_dostream : 
    public std::basic_ostream<CharT, TraitsT>
{
public:

    basic_dostream() : std::basic_ostream<CharT, TraitsT>
                (new basic_debugbuf<CharT, TraitsT>()) {}
    ~basic_dostream() 
    {
        delete rdbuf(); 
    }
};

typedef basic_dostream<char>    dostream;
typedef basic_dostream<wchar_t> wdostream;

History

  • 18-apr-2001 - Original version
  • 23-nov-2001 - Updated to use a stringbuf as suggested by Jim Barry.
    Also fixed the remaining HTML markup errors that made the code un-compileable

License

This article, along with any associated source code and files, is licensed under A Public Domain dedication

Share

About the Author

Sven Axelsson
Web Developer
Sweden Sweden
No Biography provided

You may also be interested in...

Comments and Discussions

 
GeneralThanks! Just what I needed! Pin
Mitchel Haas22-Jul-09 3:40
memberMitchel Haas22-Jul-09 3:40 
Generaljust a little adjustment .. make it work with wince Pin
isatohon11-Dec-08 23:59
memberisatohon11-Dec-08 23:59 
QuestionHow to ensure that debug stream is flushed? Pin
Freon19-Dec-07 13:15
memberFreon19-Dec-07 13:15 
If I understand STL correctly, sync() gets called when no more characters can be inserted into the output stream buffer. For debug output, I want to ensure that each call to operator<< will flush the output stream. How do I do that?
AnswerRe: How to ensure that debug stream is flushed? Pin
isatohon11-Dec-08 23:52
memberisatohon11-Dec-08 23:52 
GeneralWorks like a charm, Pin
amnonglaser30-Sep-07 13:37
memberamnonglaser30-Sep-07 13:37 
QuestionHow to declare global dostream Pin
Max235116-Jun-06 3:20
memberMax235116-Jun-06 3:20 
GeneralUnbuffered output Pin
Richard Braint10-Aug-05 3:43
memberRichard Braint10-Aug-05 3:43 
GeneralRe: Unbuffered output Pin
Henry Bruce5-Jun-07 8:50
memberHenry Bruce5-Jun-07 8:50 
GeneralRe: Unbuffered output Pin
Freon20-Dec-07 7:23
memberFreon20-Dec-07 7:23 
Generalvery handy Pin
Bernhard14-Oct-03 21:42
memberBernhard14-Oct-03 21:42 
GeneralNot possible to output more than 1023 characters with OutputDebugString() Pin
patrickdreyer19-Aug-03 23:31
memberpatrickdreyer19-Aug-03 23:31 
GeneralI built a testrunner around this Pin
Phlip3-Feb-03 10:22
memberPhlip3-Feb-03 10:22 
GeneralRe: I built a testrunner around this Pin
Sven Axelsson4-Feb-03 5:56
memberSven Axelsson4-Feb-03 5:56 
QuestionSTL container? Pin
Anonymous13-May-02 13:12
memberAnonymous13-May-02 13:12 
AnswerRe: STL container? Pin
Anonymous13-May-02 13:21
memberAnonymous13-May-02 13:21 
AnswerRe: STL container? Pin
Edwin Chen3-Jul-03 8:13
memberEdwin Chen3-Jul-03 8:13 
GeneralMemory leaks Pin
JavaBodum18-Mar-02 8:33
memberJavaBodum18-Mar-02 8:33 
GeneralRe: Memory leaks Pin
Anthony_Yio4-Nov-04 15:49
memberAnthony_Yio4-Nov-04 15:49 
Generalthread safe Pin
Anonymous14-Jun-01 5:38
memberAnonymous14-Jun-01 5:38 
GeneralUsage Pin
Markus Johansson12-Jun-01 22:52
memberMarkus Johansson12-Jun-01 22:52 
GeneralRe: Usage Pin
Anonymous20-Sep-01 10:26
memberAnonymous20-Sep-01 10:26 
GeneralRe: Usage Pin
Anonymous12-Feb-02 16:45
memberAnonymous12-Feb-02 16:45 
GeneralBetter to use basic_stringbuf Pin
Jim Barry22-Apr-01 4:12
memberJim Barry22-Apr-01 4:12 
GeneralA small bug Pin
Sven Axelsson18-Apr-01 1:31
memberSven Axelsson18-Apr-01 1:31 
Generalstlport Compatability Pin
Patrick DellEra18-Apr-01 0:16
memberPatrick DellEra18-Apr-01 0:16 
GeneralRe: stlport Compatability Pin
Sven Axelsson18-Apr-01 1:27
memberSven Axelsson18-Apr-01 1:27 
QuestionCan't Compile?? Pin
Patrick DellEra17-Apr-01 10:40
memberPatrick DellEra17-Apr-01 10:40 
AnswerRe: Can't Compile?? Pin
Sven Axelsson17-Apr-01 11:04
memberSven Axelsson17-Apr-01 11:04 
GeneralRe: Can't Compile?? Pin
Patrick DellEra17-Apr-01 12:23
memberPatrick DellEra17-Apr-01 12:23 
GeneralOutputDebugString Pin
Simon C. Smith16-Apr-01 22:31
memberSimon C. Smith16-Apr-01 22:31 
GeneralRe: OutputDebugString Pin
Sven Axelsson17-Apr-01 0:19
memberSven Axelsson17-Apr-01 0:19 
GeneralRe: OutputDebugString Pin
simon smith17-Apr-01 0:22
membersimon smith17-Apr-01 0:22 
GeneralYou may also want to check out this Pin
Daniel Lohmann13-Apr-01 3:29
memberDaniel Lohmann13-Apr-01 3:29 
GeneralBug Pin
Arnaud Brejeon12-Apr-01 21:41
memberArnaud Brejeon12-Apr-01 21:41 
GeneralRe: Bug Pin
Sven Axelsson13-Apr-01 5:40
memberSven Axelsson13-Apr-01 5:40 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.

| Advertise | Privacy | Terms of Use | Mobile
Web03 | 2.8.150819.1 | Last Updated 25 Nov 2001
Article Copyright 2001 by Sven Axelsson
Everything else Copyright © CodeProject, 1999-2015
Layout: fixed | fluid