Visual Studio 2012 C++ Standard Output
Where does fprintf(stdout/stderr) print to in Visual Studio when compiling Win32 app? I keep hearing it goes to the output but I can't see it!.
Whats the standard way of printing to the output log without having a console window in c++?
Solution 1:
If your program is linked with /SUBSYSTEM:WINDOWS you will not see the console output unless you allocate a console.
Here is code for the allocate console option. With this method you should not need to change your linker settings or create a WinMain.
static void OpenConsole()
{
int outHandle, errHandle, inHandle;
FILE *outFile, *errFile, *inFile;
AllocConsole();
CONSOLE_SCREEN_BUFFER_INFO coninfo;
GetConsoleScreenBufferInfo(GetStdHandle(STD_OUTPUT_HANDLE), &coninfo);
coninfo.dwSize.Y = 9999;
SetConsoleScreenBufferSize(GetStdHandle(STD_OUTPUT_HANDLE), coninfo.dwSize);
outHandle = _open_osfhandle((long)GetStdHandle(STD_OUTPUT_HANDLE), _O_TEXT);
errHandle = _open_osfhandle((long)GetStdHandle(STD_ERROR_HANDLE),_O_TEXT);
inHandle = _open_osfhandle((long)GetStdHandle(STD_INPUT_HANDLE),_O_TEXT );
outFile = _fdopen(outHandle, "w" );
errFile = _fdopen(errHandle, "w");
inFile = _fdopen(inHandle, "r");
*stdout = *outFile;
*stderr = *errFile;
*stdin = *inFile;
setvbuf( stdout, NULL, _IONBF, 0 );
setvbuf( stderr, NULL, _IONBF, 0 );
setvbuf( stdin, NULL, _IONBF, 0 );
std::ios::sync_with_stdio();
}
If you do not want to allocate a console directly you can also change the subsystem from /SUBSYSTEM:WINDOWS to /SUBSYSTEM:CONSOLE via changing the Subsystem of the linker settings. Remember when /SUBSYSTEM:CONSOLE is enabled the gui will still work the same as before but windows will create a console window for you along with your application.
In my Qt code that is all that is needed. However when I tried MFC in VisualStudio and set the subsystem to console via the linker setting. I got the following error:
1>------ Build started: Project: MFCApplication1, Configuration: Debug Win32 ------
1> MFCApplication1.cpp
1>msvcrtd.lib(crtexe.obj) : error LNK2019: unresolved external symbol _main referenced in function ___tmainCRTStartup
1>X:\Test\VC.110\MFCTest\MFCApplication1\Debug\MFCApplication1.exe : fatal error LNK1120: 1 unresolved externals
This is caused by the entry point defaulting to main() in console applications and WinMain in windows applications. To fix this I had to add the following to the Entry Point setting of the Advanced Linker settings: "wWinMainCRTStartup"
In the comments Ben Voigt suggested an alternate method. Using editbin to change the subsystem does not require a change in the entry point. This is indeed the case. I put removed the entry point and put windows back as the subsystem built the test application then used editbin to change the subsystem using the following command:
X:\Test\VC.110\MFCTest\MFCApplication1\Debug>editbin MFCApplication1.exe /SUBSYSTEM:CONSOLE
Microsoft (R) COFF/PE Editor Version 10.00.40219.01
Copyright (C) Microsoft Corporation. All rights reserved.
And I got the output I expected in the console:
X:\Test\VC.110\MFCTest\MFCApplication1\Debug>MFCApplication1.exe
Hello from a windows application!
Note: With the editbin method you need to renable this every time you update the executable.
And finally on either method once you have the console printf or std::cout will work. For example in my test MFC application I added the following line to the constructor of the CMFCApplication1App class:
std::cout << "Hello from a windows application!" << std::endl;