I'm working on a windows application in C++, and I'd like to use cout for debugging purposes.
It seems that the effects of cout are hidden, is there a configuration option that will allow a console window to open with my debug information?
6 Answers
You have a couple of reasonable options. One is to rename your entrypoint from WinMain to main, so it'll be built as a console application. That can still use things like RegisterClass and CreateWindow just fine.
The obvious alternative would be to use OutputDebugString instead of cout. The output from that will show up in a debugger, or any number of programs built specifically to display what it produces (basically mini-debuggers that just don't provide other debugging capabilities).
A third solution I'd consider less reasonable is to call AllocConsole to allocate a console, then write to it. If you don't mind doing all your writing with Windows-native console functions (WriteFile, WriteConsoleOutput, etc.) that's fine. Unfortunately, it won't initialize the C++ streams to work with the console, so you'll need to either open file streams pointing the console, or else find and use the (undocumented) function that initializes the streams library for the console. While this can be made to work, you end up doing extra work to write non-portable code, and little (if any) advantage to make up for it (and in this case, "non-portable" can include not even working with other versions of the same compiler, at least if you invoke the library's initialization function).
6 Comments
cout is quite portable. I think you'd end up with a grand total of two lines of Windows-specific code -- the one calling AllocConsole, and the one containing the special filename "CONOUT$". I wouldn't consider OutputDebugString a viable alternative at all, since it doesn't support any formatting, let alone compatibility with functions designed for iostreams.vsprintf, then uses OutputDebugString is trivial. A streabuf whose overflow uses OutputDebugstring isn't quite as trivial, but still not exactly rocket science.vsprintf is only trivial if you don't care about possible buffer overflow.To add a console window to a GUI application, you can use the AllocConsole API.
Then you just need to open the special file name "CONOUT$" and attach your streams to it (cout, cerr, etc)
See this explanation on MSDN.
Comments
I believe the accepted answers are actually not what you are looking for. You say you need it only for debugging, not for release. Your best options are:
a) redirect stdout and stderr to a file and then inspect the file. This you can set in the VS project Properties > Configuration Properties > Debugging > Command Arguments: you should enter >out.txt 2>&1. This will output both stdout and stderr to out.txt
b) set your debug (you say you need it only for debugging) configuration Properties > Configuration Properties > Linker > System > SubSystem to Console (/SUBSYSTEM:CONSOLE). Then you can run the project with F5, but it will hide the console window when your application finishes. If you run it with Ctrl+F5 (but then you will not have debugger attached), then it will not be hidden.
Comments
The simplest way to do this is to start a Console application from scratch:
In VisualStudio, File > New Project. Select Win32 Console Application. Select various options and create the new project.
Note that although it says Win32 Console Application, you can create x64 builds without restriction.
At this point you have an application shell. If you already have code and you want to bring it in to this new project, simply do Project > Add Existing Item... and select the files to include in the project.
1 Comment
just use OutputDebugString() but remember to either set your character set to multibyte, or if you don't want to do that, you could write your code like this:
// with multibyte character set: OutputDebugString("Failed to do something"); // without multibyte character set: OutputDebugString(L"Failed to do something");
OutputDebugString. That doesn't/won't makecoutusable (though it is, IMO, a perfectly valid alternative).