Capturing Cout in Visual Studio 2005 Output Window

How to redirect standard output to output window from Visual Studio

Straightforward standard output redirection will not work, as there is no handle corresponding to OutputDebugString. However, there should be a way:

It could be done by redirecting standard output to a pipe, and then creating a thread which would read the pipe and print anything read from it using OutputDebugString.

Note: I was contemplating for a long ago to implement this, as I am facing exactly the same problem as you do (some libraries using printf or fprintf(stderr....). However, I never really did this. I have always ended modifying the libraries instead, and therefore I do not have a working implementation, but I think it should be feasible in principle.

Visual Studio 2013: Redirecting console output to Visual Studio Output Window

The most common way of doing that is to use OutputDebugString(str);

See std::cout of .exe

The simplest approach is to rebuild the program as a console application. The option to link.exe needs to be /SUBSYSTEM:CONSOLE instead of /SUBSYSTEM:WINDOWS; presumably there is a straightforward way of specifying this in cmake.

This change shouldn't affect your GUI at all, but it will cause Windows to allocate a console if the process isn't already associated with one. Also, command line shells will usually wait for console applications to exit before continuing.

The other approach is to call AllocConsole to explicitly create a new console, or AttachConsole if you want to use an existing one. Or, of course, you could send the output to a log file.

Additional

According to a Google search, you can build the program as a console application by adding the following line to your source code:

#pragma comment(linker, "/SUBSYSTEM:CONSOLE")

This is probably the easiest solution. You can put it in an #if block if you only want the console for debug builds.

See also CMake: How to use different ADD_EXECUTABLE for debug build?

Redirect Console.Write... Methods to Visual Studio's Output Window While Debugging

Change application type to Windows before debugging. Without Console window, Console.WriteLine works like Trace.WriteLine. Don't forget to reset application back to Console type after debugging.

Visual Studio 2012 cout not shown but cerr

Ok, drescherjm was right.

I still linked to the VS9 version 3rd party library (OpenCV 2.4.2). That caused the issues.

When I did the following:

std::clog << "diff = " << cv::Mat(diff) << std::endl;

It resulted in the following output:

diff =

After that line of code, no more output was generated. So something happend inside the OpenCV code. After linking to the correct version (unfortunately there were no errors/warnings before), everything is fine again.

Thanks for your help!

Redirecting cout to a console in windows

Updated Feb 2018:

Here is the latest version of a function which fixes this problem:

void BindCrtHandlesToStdHandles(bool bindStdIn, bool bindStdOut, bool bindStdErr)
{
// Re-initialize the C runtime "FILE" handles with clean handles bound to "nul". We do this because it has been
// observed that the file number of our standard handle file objects can be assigned internally to a value of -2
// when not bound to a valid target, which represents some kind of unknown internal invalid state. In this state our
// call to "_dup2" fails, as it specifically tests to ensure that the target file number isn't equal to this value
// before allowing the operation to continue. We can resolve this issue by first "re-opening" the target files to
// use the "nul" device, which will place them into a valid state, after which we can redirect them to our target
// using the "_dup2" function.
if (bindStdIn)
{
FILE* dummyFile;
freopen_s(&dummyFile, "nul", "r", stdin);
}
if (bindStdOut)
{
FILE* dummyFile;
freopen_s(&dummyFile, "nul", "w", stdout);
}
if (bindStdErr)
{
FILE* dummyFile;
freopen_s(&dummyFile, "nul", "w", stderr);
}

// Redirect unbuffered stdin from the current standard input handle
if (bindStdIn)
{
HANDLE stdHandle = GetStdHandle(STD_INPUT_HANDLE);
if(stdHandle != INVALID_HANDLE_VALUE)
{
int fileDescriptor = _open_osfhandle((intptr_t)stdHandle, _O_TEXT);
if(fileDescriptor != -1)
{
FILE* file = _fdopen(fileDescriptor, "r");
if(file != NULL)
{
int dup2Result = _dup2(_fileno(file), _fileno(stdin));
if (dup2Result == 0)
{
setvbuf(stdin, NULL, _IONBF, 0);
}
}
}
}
}

// Redirect unbuffered stdout to the current standard output handle
if (bindStdOut)
{
HANDLE stdHandle = GetStdHandle(STD_OUTPUT_HANDLE);
if(stdHandle != INVALID_HANDLE_VALUE)
{
int fileDescriptor = _open_osfhandle((intptr_t)stdHandle, _O_TEXT);
if(fileDescriptor != -1)
{
FILE* file = _fdopen(fileDescriptor, "w");
if(file != NULL)
{
int dup2Result = _dup2(_fileno(file), _fileno(stdout));
if (dup2Result == 0)
{
setvbuf(stdout, NULL, _IONBF, 0);
}
}
}
}
}

// Redirect unbuffered stderr to the current standard error handle
if (bindStdErr)
{
HANDLE stdHandle = GetStdHandle(STD_ERROR_HANDLE);
if(stdHandle != INVALID_HANDLE_VALUE)
{
int fileDescriptor = _open_osfhandle((intptr_t)stdHandle, _O_TEXT);
if(fileDescriptor != -1)
{
FILE* file = _fdopen(fileDescriptor, "w");
if(file != NULL)
{
int dup2Result = _dup2(_fileno(file), _fileno(stderr));
if (dup2Result == 0)
{
setvbuf(stderr, NULL, _IONBF, 0);
}
}
}
}
}

// Clear the error state for each of the C++ standard stream objects. We need to do this, as attempts to access the
// standard streams before they refer to a valid target will cause the iostream objects to enter an error state. In
// versions of Visual Studio after 2005, this seems to always occur during startup regardless of whether anything
// has been read from or written to the targets or not.
if (bindStdIn)
{
std::wcin.clear();
std::cin.clear();
}
if (bindStdOut)
{
std::wcout.clear();
std::cout.clear();
}
if (bindStdErr)
{
std::wcerr.clear();
std::cerr.clear();
}
}

In order to define this function, you'll need the following set of includes:

#include <windows.h>
#include <io.h>
#include <fcntl.h>
#include <iostream>

In a nutshell, this function synchronizes the C/C++ runtime standard input/output/error handles with the current standard handles associated with the Win32 process. As mentioned in the documentation, AllocConsole changes these process handles for us, so all that's required is to call this function after AllocConsole to update the runtime handles, otherwise we'll be left with the handles that were latched when the runtime was initialized. Basic usage is as follows:

// Allocate a console window for this process
AllocConsole();

// Update the C/C++ runtime standard input, output, and error targets to use the console window
BindCrtHandlesToStdHandles(true, true, true);

This function has gone through several revisions, so check the edits to this answer if you're interested in historical information or alternatives. The current answer is the best solution to this problem however, giving the most flexibility and working on any Visual Studio version.



Related Topics



Leave a reply



Submit