How do I get console output in C++ with a Windows program? How do I get console output in C++ with a Windows program? windows windows

How do I get console output in C++ with a Windows program?


Check out Adding Console I/O to a Win32 GUI App. This may help you do what you want.

If you don't have, or can't modify the code, try the suggestions found here to redirect console output to a file.


Edit: bit of thread necromancy here. I first answered this 9ish years ago, in the early days of SO, before the (good) policy of non-link-only answers came into effect. I'll repost the code from the original article in the hope to atone for my past sins.

guicon.cpp -- A console redirection function

#include <windows.h>#include <stdio.h>#include <fcntl.h>#include <io.h>#include <iostream>#include <fstream>#ifndef _USE_OLD_IOSTREAMSusing namespace std;#endif// maximum mumber of lines the output console should havestatic const WORD MAX_CONSOLE_LINES = 500;#ifdef _DEBUGvoid RedirectIOToConsole(){    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();}#endif//End of File

guicon.h -- Interface to console redirection function

#ifndef __GUICON_H__#define __GUICON_H__#ifdef _DEBUGvoid RedirectIOToConsole();#endif#endif// End of File

test.cpp -- Demonstrating console redirection

#include <windows.h>#include <iostream>#include <fstream>#include <conio.h>#include <stdio.h>#ifndef _USE_OLD_OSTREAMSusing namespace std;#endif#include "guicon.h"#include <crtdbg.h>int APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPTSTR lpCmdLine, int nCmdShow){    #ifdef _DEBUG    RedirectIOToConsole();    #endif    int iVar;    // test stdio    fprintf(stdout, "Test output to stdout\n");    fprintf(stderr, "Test output to stderr\n");    fprintf(stdout, "Enter an integer to test stdin: ");    scanf("%d", &iVar);    printf("You entered %d\n", iVar);    //test iostreams    cout << "Test output to cout" << endl;    cerr << "Test output to cerr" << endl;    clog << "Test output to clog" << endl;    cout << "Enter an integer to test cin: ";    cin >> iVar;    cout << "You entered " << iVar << endl;    #ifndef _USE_OLD_IOSTREAMS    // test wide iostreams    wcout << L"Test output to wcout" << endl;    wcerr << L"Test output to wcerr" << endl;    wclog << L"Test output to wclog" << endl;    wcout << L"Enter an integer to test wcin: ";    wcin >> iVar;    wcout << L"You entered " << iVar << endl;    #endif    // test CrtDbg output    _CrtSetReportMode( _CRT_ASSERT, _CRTDBG_MODE_FILE );    _CrtSetReportFile( _CRT_ASSERT, _CRTDBG_FILE_STDERR );    _CrtSetReportMode( _CRT_ERROR, _CRTDBG_MODE_FILE );    _CrtSetReportFile( _CRT_ERROR, _CRTDBG_FILE_STDERR);    _CrtSetReportMode( _CRT_WARN, _CRTDBG_MODE_FILE );    _CrtSetReportFile( _CRT_WARN, _CRTDBG_FILE_STDERR);    _RPT0(_CRT_WARN, "This is testing _CRT_WARN output\n");    _RPT0(_CRT_ERROR, "This is testing _CRT_ERROR output\n");    _ASSERT( 0 && "testing _ASSERT" );    _ASSERTE( 0 && "testing _ASSERTE" );    Sleep(2000);    return 0;}//End of File


The problem with the answers like luke's and Sev's is that they unnecessarily create new FILE instances which are then leaked and can cause debug assertions in the CRT cleanup code.

freopen_s is all that is really needed:

FILE* fp = nullptr;freopen_s(&fp, "CONIN$", "r", stdin);freopen_s(&fp, "CONOUT$", "w", stdout);freopen_s(&fp, "CONOUT$", "w", stderr);

You'll probably want to do a little error checking and cleanup as well. Below is the complete solution that I currently use.

Redirecting Console Standard IO:

bool RedirectConsoleIO(){    bool result = true;    FILE* fp;    // Redirect STDIN if the console has an input handle    if (GetStdHandle(STD_INPUT_HANDLE) != INVALID_HANDLE_VALUE)        if (freopen_s(&fp, "CONIN$", "r", stdin) != 0)            result = false;        else            setvbuf(stdin, NULL, _IONBF, 0);    // Redirect STDOUT if the console has an output handle    if (GetStdHandle(STD_OUTPUT_HANDLE) != INVALID_HANDLE_VALUE)        if (freopen_s(&fp, "CONOUT$", "w", stdout) != 0)            result = false;        else            setvbuf(stdout, NULL, _IONBF, 0);    // Redirect STDERR if the console has an error handle    if (GetStdHandle(STD_ERROR_HANDLE) != INVALID_HANDLE_VALUE)        if (freopen_s(&fp, "CONOUT$", "w", stderr) != 0)            result = false;        else            setvbuf(stderr, NULL, _IONBF, 0);    // Make C++ standard streams point to console as well.    ios::sync_with_stdio(true);    // Clear the error state for each of the C++ standard streams.    std::wcout.clear();    std::cout.clear();    std::wcerr.clear();    std::cerr.clear();    std::wcin.clear();    std::cin.clear();    return result;}

Releasing a Console:

bool ReleaseConsole(){    bool result = true;    FILE* fp;    // Just to be safe, redirect standard IO to NUL before releasing.    // Redirect STDIN to NUL    if (freopen_s(&fp, "NUL:", "r", stdin) != 0)        result = false;    else        setvbuf(stdin, NULL, _IONBF, 0);    // Redirect STDOUT to NUL    if (freopen_s(&fp, "NUL:", "w", stdout) != 0)        result = false;    else        setvbuf(stdout, NULL, _IONBF, 0);    // Redirect STDERR to NUL    if (freopen_s(&fp, "NUL:", "w", stderr) != 0)        result = false;    else        setvbuf(stderr, NULL, _IONBF, 0);    // Detach from console    if (!FreeConsole())        result = false;    return result;}

Resizing Console Buffer:

void AdjustConsoleBuffer(int16_t minLength){    // Set the screen buffer to be big enough to scroll some text    CONSOLE_SCREEN_BUFFER_INFO conInfo;    GetConsoleScreenBufferInfo(GetStdHandle(STD_OUTPUT_HANDLE), &conInfo);    if (conInfo.dwSize.Y < minLength)        conInfo.dwSize.Y = minLength;    SetConsoleScreenBufferSize(GetStdHandle(STD_OUTPUT_HANDLE), conInfo.dwSize);}

Allocating a New Console:

bool CreateNewConsole(int16_t minLength){    bool result = false;    // Release any current console and redirect IO to NUL    ReleaseConsole();    // Attempt to create new console    if (AllocConsole())    {        AdjustConsoleBuffer(minLength);        result = RedirectConsoleIO();    }    return result;}

Attaching to Parent's Console:

bool AttachParentConsole(int16_t minLength){    bool result = false;    // Release any current console and redirect IO to NUL    ReleaseConsole();    // Attempt to attach to parent process's console    if (AttachConsole(ATTACH_PARENT_PROCESS))    {        AdjustConsoleBuffer(minLength);        result = RedirectConsoleIO();    }    return result;}

Calling from WinMain:

Link with /SUBSYSTEM:Windows

int APIENTRY WinMain(    HINSTANCE /*hInstance*/,    HINSTANCE /*hPrevInstance*/,    LPTSTR    /*lpCmdLine*/,    int       /*cmdShow*/){    if (CreateNewConsole(1024))    {        int i;        // test stdio        fprintf(stdout, "Test output to stdout\n");        fprintf(stderr, "Test output to stderr\n");        fprintf(stdout, "Enter an integer to test stdin: ");        scanf("%d", &i);        printf("You entered %d\n", i);        // test iostreams        std::cout << "Test output to std::cout" << std::endl;        std::cerr << "Test output to std::cerr" << std::endl;        std::clog << "Test output to std::clog" << std::endl;        std::cout << "Enter an integer to test std::cin: ";        std::cin >> i;        std::cout << "You entered " << i << std::endl;        std::cout << endl << "Press any key to continue..." << endl;        _getch();        ReleaseConsole();    }    return 0;};


You can also reopen the cout and cerr streams to output to a file as well. The following should work for this:

#include <iostream>#include <fstream>int main (){    std::ofstream file;    file.open ("cout.txt");    std::streambuf* sbuf = std::cout.rdbuf();    std::cout.rdbuf(file.rdbuf());    //cout is now pointing to a file    return 0;}