How can I redirect stdout to some visible display in a Windows Application?

You need to create pipe (with CreatePipe()), then attach stdout to it's write end with SetStdHandle(), then you can read from pipe's read end with ReadFile() and put text you get from there anywhere you like.


You can redirect stdout, stderr and stdin using freopen.

From the above link:

/* freopen example: redirecting stdout */
#include <stdio.h>

int main ()
{
  freopen ("myfile.txt","w",stdout);
  printf ("This sentence is redirected to a file.");
  fclose (stdout);
  return 0;
}

You can also run your program via command prompt like so:

a.exe > stdout.txt 2> stderr.txt

You're probably looking for something along those lines:

    #define OUT_BUFF_SIZE 512

    int main(int argc, char* argv[])
    {
        printf("1: stdout\n");

        StdOutRedirect stdoutRedirect(512);
        stdoutRedirect.Start();
        printf("2: redirected stdout\n");
        stdoutRedirect.Stop();

        printf("3: stdout\n");

        stdoutRedirect.Start();
        printf("4: redirected stdout\n");
        stdoutRedirect.Stop();

        printf("5: stdout\n");

        char szBuffer[OUT_BUFF_SIZE];
        int nOutRead = stdoutRedirect.GetBuffer(szBuffer,OUT_BUFF_SIZE);
        if(nOutRead)
            printf("Redirected outputs: \n%s\n",szBuffer);

        return 0;
    }

This class will do it:

#include <windows.h>

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

#ifndef _USE_OLD_IOSTREAMS
using namespace std;
#endif

#define READ_FD 0
#define WRITE_FD 1

#define CHECK(a) if ((a)!= 0) return -1;

class StdOutRedirect
{
    public:
        StdOutRedirect(int bufferSize);
        ~StdOutRedirect();

        int Start();
        int Stop();
        int GetBuffer(char *buffer, int size);

    private:
        int fdStdOutPipe[2];
        int fdStdOut;
};

StdOutRedirect::~StdOutRedirect()
{
    _close(fdStdOut);
    _close(fdStdOutPipe[WRITE_FD]);
    _close(fdStdOutPipe[READ_FD]);
}
StdOutRedirect::StdOutRedirect(int bufferSize)
{
    if (_pipe(fdStdOutPipe, bufferSize, O_TEXT)!=0)
    {
        //treat error eventually
    }
    fdStdOut = _dup(_fileno(stdout));
}

int StdOutRedirect::Start()
{
    fflush( stdout );
    CHECK(_dup2(fdStdOutPipe[WRITE_FD], _fileno(stdout)));
    ios::sync_with_stdio();
    setvbuf( stdout, NULL, _IONBF, 0 ); // absolutely needed
    return 0;
}

int StdOutRedirect::Stop()
{
    CHECK(_dup2(fdStdOut, _fileno(stdout)));
    ios::sync_with_stdio();
    return 0;
}

int StdOutRedirect::GetBuffer(char *buffer, int size)
{
    int nOutRead = _read(fdStdOutPipe[READ_FD], buffer, size);
    buffer[nOutRead] = '\0';
    return nOutRead;
}

Here's the result:

1: stdout
3: stdout
5: stdout
Redirected outputs:
2: redirected stdout
4: redirected stdout

When you create a process using CreateProcess() you can choose a HANDLE to which stdout and stderr are going to be written. This HANDLE can be a file to which you direct the output.

This will let you use the code without recompiling it. Just execute it and instead of using system() or whatnot, use CreateProcess().

The HANDLE you give to CreateProcess() can also be that of a pipe you created, and then you can read from the pipe and do something else with the data.