How can you view printf output in a Win32 application (entering with a WinMain) in Visual Studio 2010?
- 
                    Do you want to open a separate console window from the app, or do you want to display it in a control on the main app window? Or log it to a file? – Mark Ransom Jun 09 '10 at 19:45
 - 
                    1Actually I was hoping for something like the console window in xcode where you can see console output without having to change any code. A log showing stdout would do fine too. – Nick Van Brunt Jun 09 '10 at 20:05
 
8 Answers
Edit 2021, Visual Studio 2019
To write debug messages to the Output window use the OutputDebugStringA from debugapi.h (include windows.h)
test.c
#include <windows.h>
#include <stdio.h>
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdShow, int nCmdShow)
{
    int number = 10;
    char str[256];
    sprintf_s(str, sizeof(str), "It works! - number: %d \n", number);
    OutputDebugStringA(str);
    return 0;
}
Tested on Visual Studio 2019, Debug / x64.
Or alternatively utilize my drop-in header file.
- 9,919
 - 3
 - 61
 - 61
 
- 
                    Obviously the 256 is there only for example but I like this approach. Definitely what I had in mind. – Nick Van Brunt Jun 30 '11 at 18:19
 - 
                    Sure, just an example. You may wrap it in a class/function for convenience. Glad it helped! Cheers! – rbento Jul 05 '11 at 21:34
 - 
                    3`wchar_t str[256]; wsprintf(str, L"It works! - number: %d \n", number); OutputDebugString(str);` – Steve Pitchers Jul 07 '16 at 20:23
 - 
                    This works, but adding a temporary buffer is tedious. I like Han's answer of showing the console in addition to the UI, then I can just use `printf`. – Matthew Apr 14 '21 at 13:45
 
You'll need a console window. By far the easiest way to get one is to change a linker option: Project + Properties, Linker, System, SubSystem = Console. Add a main() method:
int main() {
    return _tWinMain(GetModuleHandle(NULL), NULL, GetCommandLine(), SW_SHOW);
}
- 922,412
 - 146
 - 1,693
 - 2,536
 
- 
                    `_tWinMain` is the main function instead called `WinMain` for a Win32 application – Rian Rizvi Jan 28 '14 at 03:57
 - 
                    In my case wWinMain. Anyway, thank you so much for this answer. I was going nuts with all the other answers I could find on the internet. A console separate from the UI was the best thing possible. – CanisLupus Mar 17 '21 at 20:05
 
I know that I have done this in the past using the AllocConsole function, but I also recall that it was just a little trickier than I expected.
A quick Google search on AllocConsole yields what is apparently a Windows Developer Journal article that seems relevant. From there, the following seems similar to what I recall, vague as it is.
void SetStdOutToNewConsole()
{
    int hConHandle;
    long lStdHandle;
    FILE *fp;
    // Allocate a console for this app
    AllocConsole();
    // Redirect unbuffered STDOUT to the console
    lStdHandle = (long)GetStdHandle(STD_OUTPUT_HANDLE);
    hConHandle = _open_osfhandle(lStdHandle, _O_TEXT);
    fp = _fdopen(hConHandle, "w");
    *stdout = *fp;
    setvbuf(stdout, NULL, _IONBF, 0);
}
- 30,738
 - 21
 - 105
 - 131
 
- 5,684
 - 21
 - 25
 
- 
                    
 - 
                    1To use `_open_osfhandle()`, you need to `#include
`, and to use `_O_TEXT`, you need to `#include – M Katz Jul 09 '18 at 06:41`.  - 
                    1Is this working for people on current windows 10? Because it's not for me. Definitely working in the past. – fret Aug 23 '18 at 07:28
 
Another way which wouldn't require changing existing printf's and also print to VS output window would go something like this:
#define printf printf2
int __cdecl printf2(const char *format, ...)
{
    char str[1024];
    va_list argptr;
    va_start(argptr, format);
    int ret = vsnprintf(str, sizeof(str), format, argptr);
    va_end(argptr);
    OutputDebugStringA(str);
    return ret;
}
...
printf("remains %s", "the same");
- 1,714
 - 1
 - 18
 - 25
 
Thanks torak for your answer. It helped me a lot.
I needed a bigger scroll back buffer so made a few additions after taking a look at the API functions. Shared here in case it helps anybody else:
void SetStdOutToNewConsole()
{
    // allocate a console for this app
    AllocConsole();
    // redirect unbuffered STDOUT to the console
    HANDLE consoleHandle = GetStdHandle(STD_OUTPUT_HANDLE);
    int fileDescriptor = _open_osfhandle((intptr_t)consoleHandle, _O_TEXT);
    FILE *fp = _fdopen( fileDescriptor, "w" );
    *stdout = *fp;
    setvbuf( stdout, NULL, _IONBF, 0 );
    // give the console window a nicer title
    SetConsoleTitle(L"Debug Output");
    // give the console window a bigger buffer size
    CONSOLE_SCREEN_BUFFER_INFO csbi;
    if ( GetConsoleScreenBufferInfo(consoleHandle, &csbi) )
    {
        COORD bufferSize;
        bufferSize.X = csbi.dwSize.X;
        bufferSize.Y = 9999;
        SetConsoleScreenBufferSize(consoleHandle, bufferSize);
    }
}
This increases the scroll back (screen buffer) height to 9999 lines.
Tested on Windows XP and Windows 7.
- 610
 - 6
 - 13
 
- 
                    3To save lookups for cut-and-pasters like me, one also needs to include
and – plasmo Feb 27 '17 at 04:54for the function and flags definitions  
Here is a page that will tell you how to do this, including sample code.
You must create a console window using AllocConsole(), then associate the C standard file handles to the HANDLEs of the new console window.
- 95
 - 7
 
- 
                    3 lines of code which solved it for me with `AllocConsole()`: https://stackoverflow.com/a/55459226/197979 – Dmitry Jan 10 '20 at 19:46
 
For MinGW use "_A_SYSTEM" instead "_O_TEXT". So ported Quintin Willison answer is as follows:
#include <io.h>
void SetStdOutToNewConsole()
{
  // allocate a console for this app
  AllocConsole();
  // redirect unbuffered STDOUT to the console
  HANDLE consoleHandle = GetStdHandle(STD_OUTPUT_HANDLE);
  int fileDescriptor = _open_osfhandle((intptr_t)consoleHandle, _A_SYSTEM);
  FILE *fp = _fdopen( fileDescriptor, "w" );
  *stdout = *fp;
  setvbuf( stdout, NULL, _IONBF, 0 );
  // give the console window a nicer title
  SetConsoleTitle(L"Debug Output");
  // give the console window a bigger buffer size
  CONSOLE_SCREEN_BUFFER_INFO csbi;
  if ( GetConsoleScreenBufferInfo(consoleHandle, &csbi) )
  {
    COORD bufferSize;
    bufferSize.X = csbi.dwSize.X;
    bufferSize.Y = 9999;
    SetConsoleScreenBufferSize(consoleHandle, bufferSize);
  }
}
- 11
 
Following is a working code
FILE* fpFile;
AllocConsole(); // or AttachConsole(ATTACH_PARENT_PROCESS); // if parent has one
freopen_s(&fpFile,"CONOUT$", "w", stdout); // redirect stdout to console
freopen_s(&fpFile,"CONOUT$", "w", stderr); // redirect stderr to console
freopen_s(&fpFile,"CONIN$", "r", stdin); // redirect stdin to console
- 
                    1Hi Davit, welcome to SO. Please take a look at the existing answers before adding your own. This is an old question and your answer nearly duplicates others that have already been posted. – irowe Mar 14 '23 at 12:13