如何使用Windows程序在C ++中获取控制台输出?
如果我有一个本地的C + + Windows程序(即入口点是WinMain)如何查看控制台function,如std :: cout的输出?
查看将控制台I / O添加到Win32 GUI应用程序 。 这可能会帮助你做你想做的事情。
如果您没有或无法修改代码,请尝试在此处find的build议将控制台输出redirect到文件。
编辑:这里的线程死灵位。 我在九十年前首先回答了这个问题,就是在SO的早期,在非链接答案(良好)政策生效之前。 我将重新发布原文中的代码,希望为我的过去的罪恶赎罪。
guicon.cpp – 控制台redirectfunction
#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 – 控制台redirectfunction的接口
#ifndef __GUICON_H__ #define __GUICON_H__ #ifdef _DEBUG void RedirectIOToConsole(); #endif #endif // End of File
test.cpp – 演示控制台redirect
#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
您也可以重新打开cout和cerrstream以输出到文件。 以下应该为此工作:
#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; }
创build一个pipe道,执行程序控制台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 }
}
不要在此引用我,但Win32 控制台API可能是您正在寻找的。 但是,如果您只是为了debugging目的而这样做,那么您可能更感兴趣的是运行DebugView并调用DbgPrint函数。
这当然假设你的应用程序要发送控制台输出,而不是从另一个应用程序读取它。 在这种情况下,pipe道可能是你的朋友。
在我的Windows桌面应用程序项目中,结合了卢克的答案和罗杰的答案在这里工作。
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(); }
转到项目>项目属性>链接器>系统,然后在右窗格中,将子系统选项设置为控制台(/ SUBSYSTEM:CONSOLE)
然后编译你的程序,并从控制台运行它,看看你的命令提示符是否显示你的输出。
由于没有控制台窗口,这是不可能的 。 (每天学点新东西 – 我从来不知道控制台的function!)
是否有可能取代您的输出呼叫? 我将经常使用TRACE或OutputDebugString将信息发送到Visual Studio输出窗口。
如果您将程序的输出发送到文件或pipe道,例如
myprogram.exe > file.txt myprogram.exe | anotherprogram.exe
或者你从另一个程序调用你的程序,并通过pipe道捕获它的输出,那么你不需要改变任何东西。 即使入口点是WinMain
,它也能正常工作。
但是,如果在控制台或Visual Studio中运行程序,则输出将不会显示在控制台或Visual Studio的“输出”窗口中。 如果你想看到输出“现场”,然后尝试其他答案之一。
基本上,这意味着标准输出就像控制台应用程序一样工作,但是它并没有连接到运行应用程序的控制台,似乎没有简单的方法来实现这一点(所有其他解决scheme在这里连接输出到一个新的控制台窗口,当你运行你的应用程序时,即使从另一个控制台也会popup)。