Where does "printf" write in a Windows Non-console Application?

printf or cout always print to stdout.

You need to start the program from command line and pipe its output to a text file to make it readable.

Otherwise you would need an outputstream to a file in tmp to be generated inside your code.

Piping can be done the following way (if your apps name would be foo):

foo > log.txt

You could then read the file log.txt if you navigate to its directory which can be found with

dir

Since your question seems to be just for information, a windows app without a console, has its stdout, stderr handles closed. Any function that tries to output to those handles, simply gets called, checks for an open handle, finds it closed, and returns without doing anything else.

You might say, your output in this case ends up nowhere to be found :)

If you want to read this output, then you need to open the handles either by allocating a console, or use one of the methods described here.


Under Windows stdout is a wrapper to the low-level functions accessing the handle returned by GetStdHandle(STD_OUTPUT_HANDLE).

When starting a non-console application by double-clicking (I tried under Windows 7, 64 bit) then GetStdHandle(STD_OUTPUT_HANDLE) will return an invalid handle. This means that printf and other commands will write nothing at all but the low-level functions internally called by printf will return an error code.

However as already said even a non-console program can be started the following way:

program_name > output_file.txt

In this case the printf output will be written to the output file.

-- EDIT --

If you wish to "catch" the printf() output and write it to MessageBox() there are two ways to achieve this:

The first one is running the program twice while the input of one instance is the standard output of the other one. The behavior could be explained by the following command line:

program_name | program_name /msgbox

The second possibility works without running two programs and without running the program twice: You may hook file handle #1. This should be at least possible when using msvcrt.dll:

HANDLE hRead,hWrite;

CreatePipe(&hRead,&hWrite,NULL,0);
dup2(_open_osfhandle(hWrite,O_WRONLY),1);

// Now printf() output can be read from handle hRead

printf("Hello world 2!\n");

// In a separate thread do:
ReadFile(hRead,...);

I am developing a visual engine and I use the following two things as a substitution for the standard input/output between pc and user that you get in console application.

1: Use sprintf (int sprintf ( char * str, const char * format, ... )). What it does is print into a string instead of stdout(you don't have to use a temporary file). After this you can use MessageBox with the string where you just printed to.

2: Make an actual console window(while keeping the main one) and redirect the stdin, stdout and stderr from the main window to the console. Here is a class for construction:

ConsoleWindowClass.h:

 #pragma once
 #include <windows.h>
 #include <stdio.h>
 #include <fcntl.h>
 #include <io.h>
 #include <iostream>
 #include <fstream>
class ConsoleWindowClass
{
public:
    ConsoleWindowClass(void);
    ~ConsoleWindowClass(void);
    void Create();
};

ConsoleWindowClass.cpp:

 #include "ConsoleWindowClass.h"

using namespace std;

// maximum mumber of lines the output console should have
static const WORD MAX_CONSOLE_LINES = 500;

ConsoleWindowClass::ConsoleWindowClass(void)
{
    Create();
}

ConsoleWindowClass::~ConsoleWindowClass(void)
{
}

void ConsoleWindowClass::Create()
{
    int hConHandle;
    long lStdHandle;
    CONSOLE_SCREEN_BUFFER_INFO coninfo;
    FILE *fp;

// allocate a console for this app
    AllocConsole();

// set the screen buffer to be big enough to let us scroll text
    GetConsoleScreenBufferInfo(GetStdHandle(STD_OUTPUT_HANDLE),&coninfo);
    coninfo.dwSize.Y = MAX_CONSOLE_LINES;
    SetConsoleScreenBufferSize(GetStdHandle(STD_OUTPUT_HANDLE),coninfo.dwSize);

// 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 );

// redirect unbuffered STDIN to the console

    lStdHandle = (long)GetStdHandle(STD_INPUT_HANDLE);
    hConHandle = _open_osfhandle(lStdHandle, _O_TEXT);

    fp = _fdopen( hConHandle, "r" );
    *stdin = *fp;
    setvbuf( stdin, NULL, _IONBF, 0 );

// redirect unbuffered STDERR to the console
    lStdHandle = (long)GetStdHandle(STD_ERROR_HANDLE);
    hConHandle = _open_osfhandle(lStdHandle, _O_TEXT);

    fp = _fdopen( hConHandle, "w" );

    *stderr = *fp;

    setvbuf( stderr, NULL, _IONBF, 0 );

// make cout, wcout, cin, wcin, wcerr, cerr, wclog and clog
// point to console as well
    ios::sync_with_stdio();
}

After this, calling printf() will print the string into the console. You can also use the console to type strings into it and they will be usable from the main window(use multi-threading so that scanf won't pause your main program).