billcoke
billcoke

Reputation: 770

Capturing cout in Visual Studio 2005 output window?

I created a C++ console app and just want to capture the cout/cerr statements in the Output Window within the Visual Studio 2005 IDE. I'm sure this is just a setting that I'm missing. Can anyone point me in the right direction?

Upvotes: 17

Views: 16220

Answers (7)

ejectamenta
ejectamenta

Reputation: 1097

Write to a std::ostringsteam and then TRACE that.

std::ostringstream oss;

oss << "w:=" << w << " u=" << u << " vt=" << vt << endl;

TRACE(oss.str().data());

Upvotes: 0

Yakov Galka
Yakov Galka

Reputation: 72519

I've finally implemented this, so I want to share it with you:

#include <vector>
#include <iostream>
#include <windows.h>
#include <boost/iostreams/stream.hpp>
#include <boost/iostreams/tee.hpp>

using namespace std;
namespace io = boost::iostreams;

struct DebugSink
{
    typedef char char_type;
    typedef io::sink_tag category;

    std::vector<char> _vec;

    std::streamsize write(const char *s, std::streamsize n)
    {
        _vec.assign(s, s+n);
        _vec.push_back(0); // we must null-terminate for WINAPI
        OutputDebugStringA(&_vec[0]);
        return n;
    }
};

int main()
{
    typedef io::tee_device<DebugSink, std::streambuf> TeeDevice;
    TeeDevice device(DebugSink(), *cout.rdbuf());
    io::stream_buffer<TeeDevice> buf(device);
    cout.rdbuf(&buf);

    cout << "hello world!\n";
    cout.flush(); // you may need to flush in some circumstances
}

BONUS TIP: If you write:

X:\full\file\name.txt(10) : message

to the output window and then double-click on it, then Visual Studio will jump to the given file, line 10, and display the 'message' in status bar. It's very useful.

Upvotes: 14

el2iot2
el2iot2

Reputation: 6616

Also, depending on your intentions, and what libraries you are using, you may want to use the TRACE macro (MFC) or ATLTRACE (ATL).

Upvotes: 0

Adam Mitz
Adam Mitz

Reputation: 6043

A combination of ben's answer and Mike Dimmick's: you would be implementing a stream_buf_ that ends up calling OutputDebugString. Maybe someone has done this already? Take a look at the two proposed Boost logging libraries.

Upvotes: 2

ben
ben

Reputation: 2024

You can capture the output of cout like this, for example:

std::streambuf* old_rdbuf = std::cout.rdbuf();
std::stringbuf new_rdbuf;
// replace default output buffer with string buffer
std::cout.rdbuf(&new_rdbuf);

// write to new buffer, make sure to flush at the end
std::cout << "hello, world" << std::endl;

std::string s(new_rdbuf.str());
// restore the default buffer before destroying the new one
std::cout.rdbuf(old_rdbuf);

// show that the data actually went somewhere
std::cout << s.size() << ": " << s;

Magicking it into the Visual Studio 2005 output window is left as an exercise to a Visual Studio 2005 plugin developer. But you could probably redirect it elsewhere, like a file or a custom window, perhaps by writing a custom streambuf class (see also boost.iostream).

Upvotes: 8

RightToLeft
RightToLeft

Reputation:

Is this a case of the output screen just flashing and then dissapearing? if so you can keep it open by using cin as your last statement before return.

Upvotes: 1

Mike Dimmick
Mike Dimmick

Reputation: 9802

You can't do this.

If you want to output to the debugger's output window, call OutputDebugString.

I found this implementation of a 'teestream' which allows one output to go to multiple streams. You could implement a stream that sends data to OutputDebugString.

Upvotes: 6

Related Questions