¿Cómo obtengo la salida de la consola en C ++ con un progtwig de Windows?

Si tengo un progtwig nativo de Windows C ++ (es decir, el punto de entrada es WinMain) ¿cómo veo el resultado de las funciones de la consola como std :: cout?

Consulte Agregar E / S de consola a una aplicación Win32 GUI . Esto puede ayudarte a hacer lo que quieras.

Si no tiene, o no puede modificar el código, intente con las sugerencias que se encuentran aquí para redirigir la salida de la consola a un archivo.


Edición: poco de necromancia de hilos aquí. La primera vez que respondí esto fue hace 9 años, en los primeros días de SO, antes de que entrara en vigencia la (buena) política de respuestas sin enlace único. Volveré a publicar el código del artículo original con la esperanza de expiar mis pecados pasados.

guicon.cpp – Una función de redirección de consola

#include  #include  #include  #include  #include  #include  #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 – Interfaz para la función de redirección de la consola

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

test.cpp – Demostración de redirección de consola

 #include  #include  #include  #include  #include  #ifndef _USE_OLD_OSTREAMS using namespace std; #endif #include "guicon.h" #include  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 

También puede volver a abrir las secuencias cout y cerr para enviarlas a un archivo también. Lo siguiente debería funcionar para esto:

 #include  #include  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; } 

crear un conducto, ejecutar la consola del progtwig CreateProcess () y leer con ReadFile () o escribir en la consola 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 } 

}

Usar una combinación de la respuesta de Lucas y la respuesta de Roger aquí funcionó para mí en mi proyecto de aplicación de escritorio de 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(); } 

No me cites sobre esto, pero la API de la consola Win32 podría ser lo que estás buscando. Sin embargo, si solo hace esto para depuración, podría estar más interesado en ejecutar DebugView y llamar a la función DbgPrint .

Por supuesto, esto supone que es su aplicación la que desea enviar la salida de la consola, no leerla desde otra aplicación. En ese caso, las tuberías pueden ser tu amigo.

Si está enviando la salida de su progtwig a un archivo o tubería, por ejemplo

 myprogram.exe > file.txt myprogram.exe | anotherprogram.exe 

o está invocando su progtwig desde otro progtwig y capturando su salida a través de un conducto, entonces no necesita cambiar nada. Simplemente funcionará, incluso si el punto de entrada es WinMain .

Sin embargo, si está ejecutando su progtwig en una consola o en Visual Studio, la salida no aparecerá en la consola o en la ventana de resultados de Visual Studio. Si desea ver el resultado “en vivo”, pruebe con una de las otras respuestas.

Básicamente, esto significa que la salida estándar funciona igual que con las aplicaciones de consola, pero no está conectada a una consola en la que está ejecutando su aplicación, y parece que no hay una manera fácil de hacerlo (todas las otras soluciones presentadas aquí se conectan la salida a una nueva ventana de consola que aparecerá cuando ejecuta su aplicación, incluso desde otra consola).

Vaya a Proyecto> Propiedades del proyecto> Enlazador> Sistema y en el panel derecho, configure la opción SubSistemas en Consola (/ SUBSISTEMA: CONSOLA)

Luego compile su progtwig y ejecútelo desde la consola para ver si el símbolo del sistema muestra sus resultados o no.

Como no hay ventana de consola, esto es imposible . (Aprende algo nuevo todos los días, ¡nunca supe las funciones de la consola!)

¿Es posible que reemplace sus llamadas de salida? A menudo usaré TRACE o OutputDebugString para enviar información a la ventana de salida de Visual Studio.