How do I print to the debug output window in a Win32 app?

231,037

Solution 1

You can use OutputDebugString. OutputDebugString is a macro that depending on your build options either maps to OutputDebugStringA(char const*) or OutputDebugStringW(wchar_t const*). In the later case you will have to supply a wide character string to the function. To create a wide character literal you can use the L prefix:

OutputDebugStringW(L"My output string.");

Normally you will use the macro version together with the _T macro like this:

OutputDebugString(_T("My output string."));

If you project is configured to build for UNICODE it will expand into:

OutputDebugStringW(L"My output string.");

If you are not building for UNICODE it will expand into:

OutputDebugStringA("My output string.");

Solution 2

If the project is a GUI project, no console will appear. In order to change the project into a console one you need to go to the project properties panel and set:

  • In "linker->System->SubSystem" the value "Console (/SUBSYSTEM:CONSOLE)"
  • In "C/C++->Preprocessor->Preprocessor Definitions" add the "_CONSOLE" define

This solution works only if you had the classic "int main()" entry point.

But if you are like in my case (an openGL project), you don't need to edit the properties, as this works better:

AllocConsole();
freopen("CONIN$", "r",stdin);
freopen("CONOUT$", "w",stdout);
freopen("CONOUT$", "w",stderr);

printf and cout will work as usual.

If you call AllocConsole before the creation of a window, the console will appear behind the window, if you call it after, it will appear ahead.

Update

freopen is deprecated and may be unsafe. Use freopen_s instead:

FILE* fp;

AllocConsole();
freopen_s(&fp, "CONIN$", "r", stdin);
freopen_s(&fp, "CONOUT$", "w", stdout);
freopen_s(&fp, "CONOUT$", "w", stderr);

Solution 3

To print to the real console, you need to make it visible by using the linker flag /SUBSYSTEM:CONSOLE. The extra console window is annoying, but for debugging purposes it's very valuable.

OutputDebugString prints to the debugger output when running inside the debugger.

Solution 4

If you want to print decimal variables:

wchar_t text_buffer[20] = { 0 }; //temporary buffer
swprintf(text_buffer, _countof(text_buffer), L"%d", your.variable); // convert
OutputDebugString(text_buffer); // print

Solution 5

Consider using the VC++ runtime Macros for Reporting _RPTN() and _RPTFN()

You can use the _RPTn, and _RPTFn macros, defined in CRTDBG.H, to replace the use of printf statements for debugging. These macros automatically disappear in your release build when _DEBUG is not defined, so there is no need to enclose them in #ifdefs.

Example...

if (someVar > MAX_SOMEVAR) {
    _RPTF2(_CRT_WARN, "In NameOfThisFunc( )," 
         " someVar= %d, otherVar= %d\n", someVar, otherVar );
}

Or you can use the VC++ runtime functions _CrtDbgReport, _CrtDbgReportW directly.

_CrtDbgReport and _CrtDbgReportW can send the debug report to three different destinations: a debug report file, a debug monitor (the Visual Studio debugger), or a debug message window.

_CrtDbgReport and _CrtDbgReportW create the user message for the debug report by substituting the argument[n] arguments into the format string, using the same rules defined by the printf or wprintf functions. These functions then generate the debug report and determine the destination or destinations, based on the current report modes and file defined for reportType. When the report is sent to a debug message window, the filename, lineNumber, and moduleName are included in the information displayed in the window.

Share:
231,037

Related videos on Youtube

izb
Author by

izb

Twitter: http://twitter.com/izb

Updated on July 08, 2022

Comments

  • izb
    izb almost 2 years

    I've got a win32 project that I've loaded into Visual Studio 2005. I'd like to be able to print things to the Visual Studio output window, but I can't for the life of me work out how. I've tried 'printf' and 'cout <<' but my messages stay stubbornly unprinted.

    Is there some sort of special way to print to the Visual Studio output window?

    • Laurie Stearn
      Laurie Stearn over 3 years
      If the VS output window defaults to showing the full path of the source cpp before each message, consider the workaround for __ FILE __.
  • izb
    izb over 14 years
    Perfect! Thanks. For completeness though, it turned out I had to do this: OutputDebugString(TEXT("Hello console world")); .. presumably due to some sort of unicode-related build option.
  • Martin Liversage
    Martin Liversage over 14 years
    @izb: I expanded my answer a bit to include information about the two versions of the function.
  • avakar
    avakar over 14 years
    +1. In general, you use the macro version and enclose the string in _T (which is the same as TEXT only shorter).
  • pm100
    pm100 over 13 years
    note that you will find it useful to have debugview from sysinternals. This allows you to see the ODS output even if Visual Studio is not running (or even installed) on the box
  • Tom Bushell
    Tom Bushell about 12 years
    +1 - much better than messing with console windows. I also had to use TEXT instead of _T - probably defined in some !@#$% .h file.
  • CDT
    CDT almost 11 years
    How can I output some string variable ? Like OutputDebugString(myStr);
  • Martin Liversage
    Martin Liversage almost 11 years
    @CDT: It depends on the type of myStr. Is it char*, wchar_t* or LPTSTR? Assuming that it is char* you simply call OutputDebugStringA(myStr) or use OutputDebugStringW with wchar_t* and OutputDebugString with LPTSTR as explained in my answer.
  • CDT
    CDT almost 11 years
    @MartinLiversage Really appreciated. It seems there's just no simple method to output debug information with VS.
  • Martin Liversage
    Martin Liversage almost 11 years
    @CDT: What is simpler than calling a function having a single parameter that is the message you want to output? Is it the ANSI/UNICODE complexity? Just use OutputDebugString and either define the appropriate preprocessor symbols to match the width of the characters you use or go with the flexible "T" types which allows you to compile to both 8 and 16 bit characters.
  • Ben Voigt
    Ben Voigt over 10 years
    EDITBIN can set subsystem to CONSOLE even if you are using WinMain rather than int main().
  • riderBill
    riderBill over 9 years
    @Zac. Thanks! The 4 lines starting with AllocConsole() worked great. Plus 1 for that. Nothing else was working, although I have gotten consoles to show up before in Win32 projects before using the /SUBSYSTEM:CONSOLE and/or _CONSOLE macros before. Don't know why the macros didn't work this evening. Could it have anything to do with using Common Language Runtime Support (/clr)?
  • vlad
    vlad over 7 years
    I was needed to see the output of existing program.
  • Mona Jalal
    Mona Jalal almost 7 years
    any idea why this doesn't output any string on the screen when I debug my code line by line? OutputDebugStringW(L"My output string."); ?
  • Martin Liversage
    Martin Liversage almost 7 years
    @MonaJalal: It is not clear from your comment what screen is so it is a bit hard to give you specific advice. If you debug your process the debugger will have a way to display the debug output. If you are using Visual Studio as your debugger the output is shown in the Output window. To actually see the output you have to select Debug from the Show output from dropdown. If you for some reason are running your process outside a debugger you can use DebugView to see debug output from all processes.
  • Nikazo
    Nikazo over 6 years
    be-careful because of the static buffer, this function is not reentrant and couldn't be used from different threads.
  • Armen Michaeli
    Armen Michaeli about 6 years
    It's worth adding to the answer or noting that _RPTF0 can be used where no variables are expected to be passed after the format string. The _RPTFN macro, on the other hand, requires at least one argument following the format string.
  • Laurie Stearn
    Laurie Stearn over 3 years
    %u for unsigned, %f for float as per reference.
  • Joseph Sible-Reinstate Monica
    Joseph Sible-Reinstate Monica almost 2 years
    Microsoft is playing Embrace, Extend, Extinguish again if they claim freopen is deprecated in favor of freopen_s. freopen is a standard C function required to be present in every hosted implementation, while freopen_s is not required by the standard and in practice only exists on Windows.