Custom application console and stderr - c++

I'm writing a class to display a custom console from inside the application. I'm also using glog to log messages to a file and at the same time to stderr. How can I have my console class listen to stderr?
I thought of making a custom fstream and the doing something like:
CustomStream cs;
auto original_buf = std::cerr.rdbuf(cs.rdbuf());
and having calls to the stream operator << sent to the console class.
Or subclassing directly from std::filebuf and calling:
CustomFilebuf fb;
auto original_buf = std::cerr.rdbuf(&fb);
Is this the right way to do it? I searched for some sample code but couldn't find very much.
Edit1: I tried using stream tee, but glog logs with stderr and not std::cerr, so I wasn't able to grab any data.

I am uncertain if this is relevant to your question, but...
ISO C99 says in 7.19.5.3, paragraph 6:
When a file is opened with update mode ('+' as the second or third character in the above list of mode argument values), both input and output may be performed on the associated stream. However, output shall not be directly followed by input without an intervening call to the fflush function [...], and input shall not be directly followed by output without an intervening call to a file positioning function, unless the input operation encounters end-of-file.
Also some say reading from stderr is "undefined behavior"...
Though you can read from stderr, as long as you flush before reading:
fwrite("x", 1, 1, stderr);
fflush(stderr);
fgetc(stderr);
Also take a look at How do I read stdout/stderr output of a child process correctly?
For anyone who would like to redirect stdout to a console Window in a Win32 app there is
AllocConsole.
I even created a simple (trivial) function to redirect stdout to the console Window:
#include <fstream>
#include <io.h>
#include <fcntl.h>
#define cMaxConsoleLines 500
void ReadyConsole() {
short int hConHandle;
long lStdHandle;
CONSOLE_SCREEN_BUFFER_INFO coninfo;
FILE *fp;
// Allocate a console for the program
AllocConsole();
// set the screen buffer to be big enough to let us scroll text
GetConsoleScreenBufferInfo(GetStdHandle(STD_OUTPUT_HANDLE), &coninfo);
coninfo.dwSize.Y = cMaxConsoleLines; // The max number of lines for the console!
SetConsoleScreenBufferSize(GetStdHandle(STD_OUTPUT_HANDLE), coninfo.dwSize);
// Redirect STDOUT to the console
lStdHandle = (long)GetStdHandle(STD_OUTPUT_HANDLE);
hConHandle = _open_osfhandle(lStdHandle, _O_TEXT);
fp = _fdopen(hConHandle, "w"); // Writing to the console
*stdout = *fp;
setvbuf(stdout, NULL, _IONBF, 0);
// -------------------------------
// Redirect STDIN to the console
lStdHandle = (long)GetStdHandle(STD_INPUT_HANDLE);
hConHandle = _open_osfhandle(lStdHandle, _O_TEXT);
fp = _fdopen(hConHandle, "r"); // Reading from the console
*stdin = *fp;
setvbuf(stdin, NULL, _IONBF, 0);
// ------------------------------
// Redirect STDERR to the console
lStdHandle = (long)GetStdHandle(STD_ERROR_HANDLE);
hConHandle = _open_osfhandle(lStdHandle, _O_TEXT);
fp = _fdopen(hConHandle, "w"); // STDERR writing to the console!
*stderr = *fp;
setvbuf(stderr, NULL, _IONBF, 0);
// ------------------------------
// Point the console to STDIO
std::ios::sync_with_stdio();
}
If you would like the console to be for Debug only, make sure to include <crtdbg.h>, which defines whether the app is in debug mode (for VC++), then, for example you could add:
#ifdef _DEBUG
// The file with the ReadyConsole function
#include <DebugStuff.h>
#endif
and to use it
#ifdef _DEBUG
ReadyConsole(); // Ready the console for debugging
#endif
#ifdef _DEBUG
fprintf(stdout, "Position, Line 1, DEBUG-INFO-HERE");
cout << "COUT is working!"; // NOTE, for cout, you will need <iostream>
#endif
Here is an additional little function (it logs the message to both stderr and stderr.log file)
void StdErr(char* Error) {
fprintf(stderr, Error);
FILE* FP = fopen("stderr.log", "a");
fputs(Error, FP);
fclose(FP);
}

Related

Getting line input from a AllocConsole C++

A team member added the following code to our GUI Ogre project to add a console (so that we are able to see cout as we are debugging...
We are now running way behind time, and we need text interaction with the game, I was going to make a console, but it is plausibly a big time hole... So I thought hey! Why not use the console he attached!! unfortunatly, I was inable to type into it when I attempted, thus I wouldn't be able to send a command to the console :\
Is there any way to enable writing into the console (atm the way he's done it if you hit any key (as such as 'a') nothing goes into the console, therefore I can't wait for enter and then phase the string typed into the win32 console)
Here's his code (I also added the link encase somone has a rough idea, but they want to read about it again, I don't know the exact guide he followed, but it was very simular)
void showWin32Console()
{
static const WORD MAX_CONSOLE_LINES = 1000;
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
std::ios::sync_with_stdio();
}
AllocConsole() just gives you a new console, it doesn't change existing stdin/stdout - so the handles you get back from GetStdHandle will still be their former values. Instead you have to open the special devices "CONIN$"/"CONOUT$". Turns out that reassigning stdin/stdout to this new console is actually fairly simple, using freopen:
BOOL f = AllocConsole();
freopen("CONIN$", "r", stdin);
freopen("CONOUT$", "w", stdout);
freopen("CONOUT$", "w", stderr);
...and presto, all further access to standard input or output will now go to your new console.
(This doesn't change what the Win32's view of your standard input/output handles are, by the way, so if there happens to be other code in the process that calls GetStdHandle(STD_INPUT_HANDLE) etc instead of using the CRT's stdio, those will still return the original values that are not related to your new console. If you need to change those too, then you may need to play around with opening CONIN$/CONOUT$ manually and using SetStdHandle to fix up those.)

C++ - Qt - Visual Studio 2010 - application with both gui and console

If no arguments are given to the program it launches as a GUI application, if it is given args it is run through the command line. I was able to get visual studio to display and print to the console with Properties>Linker>SubSystem (Console/SUBSYSTEM:CONSOLE), but this makes it so that the console always displays when the application is launched, how can I selectively display the console so that when the app is run with the GUI it does not appear. I have looked through the site, but all I have found is how to set it to only be a windows application, and I need it to function as both
Thanks!!!
This works I guess:
#include <QtGui/QApplication>
#include <QtGui/QMainWindow>
int
main(int n_app_args, char **app_arg)
{
QCoreApplication * application = 0;
if ( n_app_args == 1 )
{
application = new QCoreApplication(n_app_args, app_arg);
}
else
{
application = new QApplication(n_app_args, app_arg);
QMainWindow * mainWindow = new QMainWindow();
mainWindow->show();
}
return application->exec();
}
Call it with an argument and you get a little (empty) window. Call it with no argument and no window.
Here's some code I had lying around that creates a console and attaches input and output to it:
#include <Windows.h>
#include <stdio.h>
#include <io.h>
#include <fcntl.h>
void Console::createConsole()
{
AllocConsole();
SetConsoleTitle("Debug console");
int hConHandle;
long lStdHandle;
FILE *fp; // 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 );
}
I haven't used Qt but you should be able to stick that somewhere and make it work.
Edit: added the headers needed
You can have it using the windows subsystem, and calling AllocConsole when you need a console while the application has a gui as well.

C++ / SDL Debugging with console window

I am playing around with some OpenGL, using SDL to handle the window / input etc. Currently I am displaying any information I want to see to a HUD. Well, this is getting over-cumbersome, and I was wondering if there is a simple way to open up a separate console window to report this information to me. I am still new to C++ so go easy on me if this is an obvious one.
The following code is for Windows. I always find it handy to keep around the ability to create a console window on demand:
int hConHandle;
intptr_t 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 = 500;
SetConsoleScreenBufferSize(GetStdHandle(STD_OUTPUT_HANDLE), coninfo.dwSize);
// redirect unbuffered STDOUT to the console
lStdHandle = (intptr_t)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 = (intptr_t)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 = (intptr_t)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
std::ios::sync_with_stdio();
//Keep our window in focus
SetForegroundWindow(m_hWnd); // Slightly Higher Priority
SetFocus(m_hWnd); // Sets Keyboard Focus To The Window
This code assumes that the HWND is in a variable called m_hWnd; it's copied from a class wrapper I use. How you get the HWND from SDL is up to you, however.
To free the console, call this:
FreeConsole();
AllocConsole and FreeConsole are Win32 API functions.
In Linker -> System in your project's properties, check that the SubSystem is "Console (/SUBSYSTEM:CONSOLE)". That causes a separate console window to be brought up when you run your program. If your current entry point isn't main, then you'll need to change it to that if you do this though.
If you're running from a command line and use printf() you should see messages logged out to your terminal window. Otherwise you could log to a file and use tail -f on *nix style boxes to view the output as it appears.
What environment are you using? Most IDEs will show this output in their debug output windows as well.

No cout from wxWidget application, but with Eclipse it works fine

my wxWidget Application does not make any std::cout << "xyz" ... on a windows console (Windows XP) when it is startet from a console by e.g.: "call MyApplication.exe". It will produce no output at all. The Application instead rises correctly and works fine. All Buttons and Widgets on the Frame have their functions working.
When I run my application from Eclipse, it produces its outputs as it should be to Eclipse' console.
So, why i can't see any output on windows console? What do i have to activate?
I've always been curious about this, so I followed the links provided in Bo Persson's answer and pieced together some code. To use it, just define a UseConsole object in main.
UseConsole.h:
class UseConsole
{
public:
UseConsole();
~UseConsole();
private:
bool m_good;
};
UseConsole.cpp:
#include <windows.h>
#include <stdio.h>
#include <fcntl.h>
#include <io.h>
#include <iostream>
#include <fstream>
#include "UseConsole.h"
// The following function is taken nearly verbatim from
// http://www.halcyon.com/~ast/dload/guicon.htm
void RedirectIOToConsole()
{
int hConHandle;
long lStdHandle;
FILE *fp;
// 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
std::ios::sync_with_stdio();
}
UseConsole::UseConsole()
{
m_good = !!AttachConsole(ATTACH_PARENT_PROCESS);
if (m_good)
RedirectIOToConsole();
}
UseConsole::~UseConsole()
{
if (m_good)
FreeConsole();
}
A windowed application by default doesn't have a console. You can create one if you like to have one anyway.
See the answers to this question:
Visual C++ Enable Console
When running in an IDE, the IDE often does that for you.
If you already have a console window open, you can alternatively attach to the parent process' console using AttachConsole(ATTACH_PARENT_PROCESS).
http://msdn.microsoft.com/en-us/library/ms681952(v=vs.85).aspx

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

If I have a native C++ windows program (i.e. the entry point is WinMain) how do I view output from console functions like std::cout?
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_IOSTREAMS
using namespace std;
#endif
// maximum mumber of lines the output console should have
static const WORD MAX_CONSOLE_LINES = 500;
#ifdef _DEBUG
void 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 _DEBUG
void 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_OSTREAMS
using 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 some of the other answers 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;
}
Actually there is a much simpler solution than any proposed so far. Your Windows program will have a WinMain function so just add this "dummy" main function as well
int main()
{
return WinMain(GetModuleHandle(NULL), NULL, GetCommandLineA(), SW_SHOWNORMAL);
}
You can now compile using MSVC like this
cl /nologo /c /EHsc myprog.c
link /nologo /out:myprog.exe /subsystem:console myprog.obj user32.lib gdi32.lib
(you may need to add more library links)
When you run the program any printf will be written to the command prompt.
If you are using gcc (mingw) to compile for Windows you don't need a dummy main function, just do
gcc -o myprog.exe myprog.c -luser32 -lgdi32
(ie avoid using the -mwindows flag which will prevent writing to a console. That flag will be useful when you create the final GUI release) Again you may need to specify more libraries if using more windows features)
If you are sending the output of your program to a file or pipe, e.g.
myprogram.exe > file.txt
myprogram.exe | anotherprogram.exe
or you are invoking your program from another program and capturing its output through a pipe, then you don't need to change anything. It will just work, even if the entry point is WinMain.
However, if you are running your program in a console or in Visual Studio, then the output will not appear in the console or in the Output window of Visual Studio. If you want to see the output "live", then try one of the other answers.
Basically, this means that standard output works just like with console applications, but it isn't connected to a console in which you are running your application, and there seems to be no easy way to do that (all the other solutions presented here connect the output to a new console window that will pop up when you run your application, even from another console).
Using a combination of luke's answer and Roger's answer here worked for me in my Windows Desktop Application project.
void RedirectIOToConsole() {
//Create a console for this application
AllocConsole();
// Get STDOUT handle
HANDLE ConsoleOutput = GetStdHandle(STD_OUTPUT_HANDLE);
int SystemOutput = _open_osfhandle(intptr_t(ConsoleOutput), _O_TEXT);
FILE *COutputHandle = _fdopen(SystemOutput, "w");
// Get STDERR handle
HANDLE ConsoleError = GetStdHandle(STD_ERROR_HANDLE);
int SystemError = _open_osfhandle(intptr_t(ConsoleError), _O_TEXT);
FILE *CErrorHandle = _fdopen(SystemError, "w");
// Get STDIN handle
HANDLE ConsoleInput = GetStdHandle(STD_INPUT_HANDLE);
int SystemInput = _open_osfhandle(intptr_t(ConsoleInput), _O_TEXT);
FILE *CInputHandle = _fdopen(SystemInput, "r");
//make cout, wcout, cin, wcin, wcerr, cerr, wclog and clog point to console as well
ios::sync_with_stdio(true);
// Redirect the CRT standard input, output, and error handles to the console
freopen_s(&CInputHandle, "CONIN$", "r", stdin);
freopen_s(&COutputHandle, "CONOUT$", "w", stdout);
freopen_s(&CErrorHandle, "CONOUT$", "w", stderr);
//Clear the error state for each of the C++ standard stream objects. We need to do this, as
//attempts to access the standard streams before they refer to a valid target will cause the
//iostream objects to enter an error state. In versions of Visual Studio after 2005, this seems
//to always occur during startup regardless of whether anything has been read from or written to
//the console or not.
std::wcout.clear();
std::cout.clear();
std::wcerr.clear();
std::cerr.clear();
std::wcin.clear();
std::cin.clear();
}
creating a pipe, execute the program console CreateProcess() and read with ReadFile() or writes in console WriteFile()
HANDLE hRead ; // ConsoleStdInput
HANDLE hWrite; // ConsoleStdOutput and ConsoleStdError
STARTUPINFO stiConsole;
SECURITY_ATTRIBUTES segConsole;
PROCESS_INFORMATION priConsole;
segConsole.nLength = sizeof(segConsole);
segConsole.lpSecurityDescriptor = NULL;
segConsole.bInheritHandle = TRUE;
if(CreatePipe(&hRead,&hWrite,&segConsole,0) )
{
FillMemory(&stiConsole,sizeof(stiConsole),0);
stiConsole.cb = sizeof(stiConsole);
GetStartupInfo(&stiConsole);
stiConsole.hStdOutput = hWrite;
stiConsole.hStdError = hWrite;
stiConsole.dwFlags = STARTF_USESHOWWINDOW | STARTF_USESTDHANDLES;
stiConsole.wShowWindow = SW_HIDE; // execute hide
if(CreateProcess(NULL, "c:\\teste.exe",NULL,NULL,TRUE,NULL,
NULL,NULL,&stiConsole,&priConsole) == TRUE)
{
//readfile and/or writefile
}
}
Go to Project>Project Properties>Linker>System and in the right pane, set SubSystems option to Console(/SUBSYSTEM:CONSOLE)
Then compile your program and run it from console to see whether you command prompt shows your outputs or not.
Don't quote me on this, but the Win32 console API might be what you're looking for. If you're just doing this for debugging purposes, however, you might be more interested in running DebugView and calling the DbgPrint function.
This of course assumes its your application you want sending console output, not reading it from another application. In that case, pipes might be your friend.
As mentioned there and there the easiest solution is to use your Project Property Pages to switch back and forth between CONSOLE and WINDOWS SubSytems to enable or disable console output at will.
Your program will just need main and WinMain entry points to make sure both configuration are compiling.
The main function simply calling WinMain as shown below for instance:
int main()
{
cout << "Output standard\n";
cerr << "Output error\n";
return WinMain(GetModuleHandle(NULL), NULL, GetCommandLineA(), SW_SHOWNORMAL);
}
Since there's no console window, this is impossible difficult. (Learn something new every day - I never knew about the console functions!)
Is it possible for you to replace your output calls? I will often use TRACE or OutputDebugString to send information to the Visual Studio output window.