sirve que para getstdhandle c++ c winapi visual-c++ stdout

c++ - que - ¿Dónde se escribe "printf" en una aplicación de Windows sin consola?



getstdhandle c++ (4)

Si elijo crear una aplicación de Windows sin consola e implementar printf/cout en el código, ¿dónde escribe printf/cout ? ¿Escribe en el buffer stdout ? En caso afirmativo, ¿hay alguna forma de leerlo desde stdout e imprimirlo en algún archivo de texto o hacer un MessageBox con el texto (solo para verificar que lo he leído correctamente)?

EDITAR :: Solo para aclarar que no quiero redirigir la salida a ninguna parte. Me gustaría saber, ¿dónde escribe printf/cout ? Y si se escribe en algún búfer predeterminado, ¿hay una manera de leer la salida, solo para verificar que he leído la salida correcta y del búfer correcto? Por favor, no me den soluciones para redirigir el "stdout" .


Bajo Windows stdout es un contenedor para las funciones de bajo nivel que acceden al identificador devuelto por GetStdHandle(STD_OUTPUT_HANDLE) .

Al iniciar una aplicación que no sea de consola haciendo doble clic (probé con Windows 7, 64 bit), GetStdHandle(STD_OUTPUT_HANDLE) devolverá un identificador no válido. Esto significa que printf y otros comandos no escribirán nada en absoluto, pero las funciones de bajo nivel llamadas internamente por printf devolverán un código de error.

Sin embargo, como ya se dijo, incluso un programa que no sea de consola se puede iniciar de la siguiente manera:

program_name > output_file.txt

En este caso, la salida de printf se escribirá en el archivo de salida.

- EDITAR -

Si desea "capturar" la salida de printf() y escribirla en MessageBox() hay dos maneras de lograr esto:

El primero ejecuta el programa dos veces, mientras que la entrada de una instancia es la salida estándar de la otra. El comportamiento podría explicarse por la siguiente línea de comando:

program_name | program_name /msgbox

La segunda posibilidad funciona sin ejecutar dos programas y sin ejecutar el programa dos veces: puede enganchar el identificador de archivo # 1. Esto debería ser al menos posible cuando se usa msvcrt.dll:

HANDLE hRead,hWrite; CreatePipe(&hRead,&hWrite,NULL,0); dup2(_open_osfhandle(hWrite,O_WRONLY),1); // Now printf() output can be read from handle hRead printf("Hello world 2!/n"); // In a separate thread do: ReadFile(hRead,...);


Debido a que su pregunta parece ser solo informativa, una aplicación de Windows sin consola tiene su stdout, stderr se cierra. Cualquier función que intente dar salida a esos manejadores, simplemente recibe una llamada, busca un manejador abierto, lo encuentra cerrado y regresa sin hacer nada más.

Se podría decir que, en este caso, su resultado no se encuentra en ninguna parte :)

Si desea leer esta salida, necesita abrir los manejadores ya sea asignando una consola o usando uno de los métodos descritos aquí.


Estoy desarrollando un motor visual y utilizo las siguientes dos cosas como una sustitución de la entrada / salida estándar entre la PC y el usuario que obtiene en la aplicación de consola.

1: Utilice sprintf (int sprintf ( char * str, const char * format, ... )) . Lo que hace es imprimir en una cadena en lugar de stdout (no tiene que usar un archivo temporal). Después de esto, puede usar MessageBox con la cadena donde acaba de imprimir.

2: Cree una ventana de consola real (mientras mantiene la ventana principal) y redirija el stdin , stdout y stderr de la ventana principal a la consola. Aquí hay una clase para la construcción:

ConsoleWindowClass.h:

#pragma once #include <windows.h> #include <stdio.h> #include <fcntl.h> #include <io.h> #include <iostream> #include <fstream> class ConsoleWindowClass { public: ConsoleWindowClass(void); ~ConsoleWindowClass(void); void Create(); };

ConsoleWindowClass.cpp:

#include "ConsoleWindowClass.h" using namespace std; // maximum mumber of lines the output console should have static const WORD MAX_CONSOLE_LINES = 500; ConsoleWindowClass::ConsoleWindowClass(void) { Create(); } ConsoleWindowClass::~ConsoleWindowClass(void) { } void ConsoleWindowClass::Create() { 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(); }

Después de esto, llamar a printf() imprimirá la cadena en la consola. También puede usar la consola para escribir cadenas en ella y se podrán utilizar desde la ventana principal (use subprocesos múltiples para que scanf no detenga su programa principal).


printf o cout siempre imprime a stdout .

Debe iniciar el programa desde la línea de comandos y canalizar su salida a un archivo de texto para que sea legible.

De lo contrario, necesitaría una secuencia de salida a un archivo en tmp para generarse dentro de su código.

La canalización se puede hacer de la siguiente manera (si el nombre de su aplicación es foo):

foo > log.txt

Luego puede leer el archivo log.txt si navega a su directorio que se puede encontrar con

dir