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?
如果我有一个本地的c++ windows程序(即入口点是WinMain),我如何查看来自控制台函数的输出,比如std::cout?
8 个解决方案
#1
19
Check out Adding Console I/O to a Win32 GUI App. This may help you do what you want.
检查添加控制台I/O到一个Win32 GUI应用程序。这可以帮助你做你想做的。
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.
编辑:这里的线程死灵。我第一次回答这个问题是在9年前,在此之前,在(好的)非链接的政策开始生效之前。我将重新发布原始文章中的代码,希望能弥补我过去的过错。
guicon.cpp -- A console redirection function
guicon。cpp——一个控制台重定向功能。
#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
guicon。h——控制台重定向功能的接口。
#ifndef __GUICON_H__
#define __GUICON_H__
#ifdef _DEBUG
void RedirectIOToConsole();
#endif
#endif
// End of File
test.cpp -- Demonstrating console redirection
测试。cpp——演示控制台重定向。
#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
#2
9
You can also reopen the cout and cerr streams to output to a file as well. The following should work for this:
您还可以重新打开cout和cerr流,以输出到文件。下面的工作应该是这样的:
#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;
}
#3
3
creating a pipe, execute the program console CreateProcess() and read with ReadFile() or writes in console WriteFile()
创建一个管道,执行程序控制台CreateProcess(),并使用ReadFile()读取或写入控制台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
}
}
}
#4
3
Using a combination of luke's answer and Roger's answer here worked for me in my Windows Desktop Application project.
在我的Windows桌面应用程序项目中,使用luke的答案和Roger的答案组合在一起。
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();
}
#5
2
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.
不要引用我的话,但是Win32控制台API可能就是你要找的。但是,如果您只是为了调试目的而这样做,那么您可能更感兴趣的是运行DebugView并调用DbgPrint函数。
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.
这当然是假定您的应用程序需要发送控制台输出,而不是从另一个应用程序读取它。在这种情况下,管道可能是你的朋友。
#6
2
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
.
或者您从另一个程序调用程序并通过管道捕获它的输出,那么您不需要改变任何东西。它只会工作,即使入口点是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.
但是,如果您在控制台或Visual Studio中运行您的程序,那么输出将不会出现在控制台或Visual Studio的输出窗口中。如果您希望看到输出“live”,那么尝试另一个答案。
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).
基本上,这意味着标准输出作品就像控制台应用程序,但它不是连接到控制台,您正在运行您的应用程序,和似乎没有简单方法(这里提出其他解决方案输出连接到一个新的控制台窗口将弹出当您运行您的应用程序,甚至从另一个控制台)。
#7
1
Go to Project>Project Properties>Linker>System and in the right pane, set SubSystems option to Console(/SUBSYSTEM:CONSOLE)
到>项目的>Linker>系统,在右侧面板中,将子系统选项设置为控制台(/子系统:控制台)
Then compile your program and run it from console to see whether you command prompt shows your outputs or not.
然后编译程序并从控制台运行它,看看是否命令提示符显示了输出。
#8
0
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.
您是否可以替换您的输出调用?我将经常使用TRACE或OutputDebugString将信息发送到Visual Studio输出窗口。
#1
19
Check out Adding Console I/O to a Win32 GUI App. This may help you do what you want.
检查添加控制台I/O到一个Win32 GUI应用程序。这可以帮助你做你想做的。
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.
编辑:这里的线程死灵。我第一次回答这个问题是在9年前,在此之前,在(好的)非链接的政策开始生效之前。我将重新发布原始文章中的代码,希望能弥补我过去的过错。
guicon.cpp -- A console redirection function
guicon。cpp——一个控制台重定向功能。
#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
guicon。h——控制台重定向功能的接口。
#ifndef __GUICON_H__
#define __GUICON_H__
#ifdef _DEBUG
void RedirectIOToConsole();
#endif
#endif
// End of File
test.cpp -- Demonstrating console redirection
测试。cpp——演示控制台重定向。
#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
#2
9
You can also reopen the cout and cerr streams to output to a file as well. The following should work for this:
您还可以重新打开cout和cerr流,以输出到文件。下面的工作应该是这样的:
#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;
}
#3
3
creating a pipe, execute the program console CreateProcess() and read with ReadFile() or writes in console WriteFile()
创建一个管道,执行程序控制台CreateProcess(),并使用ReadFile()读取或写入控制台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
}
}
}
#4
3
Using a combination of luke's answer and Roger's answer here worked for me in my Windows Desktop Application project.
在我的Windows桌面应用程序项目中,使用luke的答案和Roger的答案组合在一起。
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();
}
#5
2
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.
不要引用我的话,但是Win32控制台API可能就是你要找的。但是,如果您只是为了调试目的而这样做,那么您可能更感兴趣的是运行DebugView并调用DbgPrint函数。
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.
这当然是假定您的应用程序需要发送控制台输出,而不是从另一个应用程序读取它。在这种情况下,管道可能是你的朋友。
#6
2
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
.
或者您从另一个程序调用程序并通过管道捕获它的输出,那么您不需要改变任何东西。它只会工作,即使入口点是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.
但是,如果您在控制台或Visual Studio中运行您的程序,那么输出将不会出现在控制台或Visual Studio的输出窗口中。如果您希望看到输出“live”,那么尝试另一个答案。
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).
基本上,这意味着标准输出作品就像控制台应用程序,但它不是连接到控制台,您正在运行您的应用程序,和似乎没有简单方法(这里提出其他解决方案输出连接到一个新的控制台窗口将弹出当您运行您的应用程序,甚至从另一个控制台)。
#7
1
Go to Project>Project Properties>Linker>System and in the right pane, set SubSystems option to Console(/SUBSYSTEM:CONSOLE)
到>项目的>Linker>系统,在右侧面板中,将子系统选项设置为控制台(/子系统:控制台)
Then compile your program and run it from console to see whether you command prompt shows your outputs or not.
然后编译程序并从控制台运行它,看看是否命令提示符显示了输出。
#8
0
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.
您是否可以替换您的输出调用?我将经常使用TRACE或OutputDebugString将信息发送到Visual Studio输出窗口。