2009-08-26 32 views
65

Tengo un proyecto de win32 que cargué en Visual Studio 2005. Me gustaría poder imprimir cosas en la ventana de salida de Visual Studio, pero no puedo averiguar cómo. He intentado con 'printf' y 'cout < <', pero mis mensajes permanecen obstinadamente sin imprimir.¿Cómo imprimo en la ventana de salida de depuración en una aplicación Win32?

¿Hay alguna forma especial de imprimir en la ventana de salida de Visual Studio?

+8

Tenga en cuenta que la ventana de salida de Visual Studio no es la consola. Ambos son "ventanas con texto en ellos", pero son diferentes detrás de las escenas. – MSalters

Respuesta

106

Puede usar OutputDebugString. OutputDebugString es una macro que, según las opciones de compilación, se asigna a OutputDebugStringA(char const*) o OutputDebugStringW(wchar_t const*). En el caso posterior, deberá proporcionar una cadena de caracteres amplia a la función. Para crear un carácter ancho literal puede utilizar el L prefijo:

OutputDebugStringW(L"My output string."); 

Normalmente, se utilizará la versión macro junto con el _T macro como esta:

OutputDebugString(_T("My output string.")); 

Si proyecta está configurado para construir para UNICODE que se extenderá a:

OutputDebugStringW(L"My output string."); 

Si no está construyendo para UNICODE que se extenderá a:

OutputDebugStringA("My output string."); 
+2

¡Perfecto! Gracias. Para completar, sin embargo, resultó que tenía que hacer esto: OutputDebugString (TEXT ("Hola mundo de la consola")); .. presumiblemente debido a algún tipo de opción de construcción relacionada con unicode. – izb

+0

@izb: Expandí un poco mi respuesta para incluir información sobre las dos versiones de la función. –

+0

+1. En general, utiliza la versión de macro y encierra la cadena en '_T' (que es lo mismo que' TEXT' solo más corto). – avakar

12

Para imprimir en la consola real, es necesario para que sea visible mediante el uso de la bandera enlazador /SUBSYSTEM:CONSOLE. La ventana extra de la consola es molesta, pero para fines de depuración es muy valiosa.

OutputDebugString imprime en la salida del depurador cuando se ejecuta dentro del depurador.

+5

También puede asignar su propia consola usando AllocConsole() –

2

Su proyecto Win32 probablemente sea un proyecto de GUI, no un proyecto de consola. Esto causa una diferencia en el encabezado ejecutable. Como resultado, su proyecto de GUI será responsable de abrir su propia ventana. Sin embargo, puede ser una ventana de consola. Llame al AllocConsole() para crearlo y use las funciones de la consola Win32 para escribir en él.

24

Si el proyecto es un proyecto de GUI, no aparecerá ninguna consola. Con el fin de cambiar el proyecto en una consola uno tiene que ir al panel de propiedades del proyecto y establecer:

  • en "enlazador > Sistema-> subsistema" el valor "consola (/ SUBSISTEMA: CONSOLA) "
  • En" C/C++ -> Preprocessor-> Definiciones del preprocesador "añadir el" _CONSOLE "definir

Esta solución sólo funciona si usted tenía el clásico" int main() "punto de entrada.

Pero si usted es como en mi caso (un proyecto de OpenGL), que no es necesario para editar las propiedades, ya que esto funciona mejor:

AllocConsole(); 
freopen("CONIN$", "r",stdin); 
freopen("CONOUT$", "w",stdout); 
freopen("CONOUT$", "w",stderr); 

printf y cout funcionarán como de costumbre.

Si llama a AllocConsole antes de la creación de una ventana, la consola aparecerá detrás de la ventana, si la llama después, aparecerá más adelante.

+0

'EDITBIN' puede establecer el subsistema en' CONSOLE' incluso si está utilizando 'WinMain' en lugar de' int main() '. –

+1

@Zac. ¡Gracias! Las 4 líneas que comienzan con AllocConsole() funcionó muy bien. Más 1 para eso. Nada más funcionaba, aunque he conseguido consolas para mostrar antes en proyectos Win32 antes de usar las macros/SUBSYSTEM: CONSOLE y/o _CONSOLE antes. No sé por qué las macros no funcionaron esta noche. ¿Podría tener algo que ver con el uso de * Common Language Runtime Support (/ clr) *? – riderBill

2

considerar el uso de la VC++ macros de tiempo de ejecución para Reporting _RPTN() and _RPTFN()

Puede utilizar el _RPTn y macros _RPTFn, definidos en crtdbg.h, a reemplazar el uso de printf para la depuración. Estas macros desaparecen automáticamente en su compilación de lanzamiento cuando _DEBUG no está definido, por lo que no es necesario que las incluya en #ifdefs.

Ejemplo ...

if (someVar > MAX_SOMEVAR) { 
    _RPTF2(_CRT_WARN, "In NameOfThisFunc()," 
     " someVar= %d, otherVar= %d\n", someVar, otherVar); 
} 

O puede usar el VC++ funciones de tiempo de ejecución _CrtDbgReport, _CrtDbgReportW directamente.

_CrtDbgReport y _CrtDbgReportW pueden enviar el informe de depuración a tres destinos diferentes: un archivo de informe de depuración, un monitor de depuración (el depurador de Visual Studio), o una ventana de mensajes de depuración.

_CrtDbgReport y _CrtDbgReportW crean el mensaje de usuario para el informe de depuración sustituyendo el argumento [n] argumentos en la cadena de formato , utilizando las mismas reglas definidas por el printf o wprintf funciones. Estas funciones luego generan el informe de depuración y determinan el destino o los destinos, según los modos y los archivos del informe actual definidos para reportType. Cuando el informe se envía a una ventana de mensaje de depuración , el nombre de archivo, lineNumber y moduleName son incluidos en la información que se muestra en la ventana.

1

Si desea imprimir las variables decimales:

wchar_t text_buffer[20] = { 0 }; //temporary buffer 
swprintf(text_buffer, _countof(text_buffer), L"%d", your.variable); // convert 
OutputDebugString(text_buffer); // print 
1

Si necesita ver la salida de un programa existente que ampliamente utilizado printf w/o cambiar el código (o con cambios mínimos) que pueda redefina printf de la siguiente manera y agréguelo al encabezado común (stdafx.h).

int print_log(const char* format, ...) 
{ 
    static char s_printf_buf[1024]; 
    va_list args; 
    va_start(args, format); 
    _vsnprintf(s_printf_buf, sizeof(s_printf_buf), format, args); 
    va_end(args); 
    OutputDebugStringA(s_printf_buf); 
    return 0; 
} 

#define printf(format, ...) \ 
     print_log(format, __VA_ARGS__) 
+0

tenga cuidado debido al búfer estático, esta función no se reentrante y no podría utilizarse desde diferentes subprocesos. – Nikazo

0

Estaba buscando una forma de hacer esto yo mismo y encontré una solución simple.

Supongo que comenzó un Proyecto Win32 predeterminado (aplicación Windows) en Visual Studio, que proporciona una función "WinMain". De forma predeterminada, Visual Studio establece el punto de entrada en "SUBSISTEMA: WINDOWS". Es necesario cambiar primero esto de ir a:

Proyecto -> Propiedades -> Enlazador -> Sistema -> Subsistema

y seleccione "Consola (/ SUBSISTEMA: Consola)" de la lista desplegable.

Ahora, el programa no se ejecutará, ya que se necesita una función "principal" en lugar de la función "WinMain".

Ahora puede agregar una función "principal" como lo haría normalmente en C++. Después de esto, para iniciar el programa GUI, puede llamar a la función "WinMain" desde dentro de la función "principal".

La parte inicial de su programa ahora debe ser algo como esto:

#include <iostream> 

using namespace std; 

// Main function for the console 
int main(){ 

    // Calling the wWinMain function to start the GUI program 
    // Parameters: 
    // GetModuleHandle(NULL) - To get a handle to the current instance 
    // NULL - Previous instance is not needed 
    // NULL - Command line parameters are not needed 
    // 1 - To show the window normally 
    wWinMain(GetModuleHandle(NULL), NULL,NULL, 1); 

    system("pause"); 
    return 0; 
} 

// Function for entry into GUI program 
int APIENTRY wWinMain(_In_ HINSTANCE hInstance, 
        _In_opt_ HINSTANCE hPrevInstance, 
        _In_ LPWSTR lpCmdLine, 
        _In_ int  nCmdShow) 
{ 
    // This will display "Hello World" in the console as soon as the GUI begins. 
    cout << "Hello World" << endl; 
. 
. 
. 

Result of my implementation

Ahora puede utilizar las funciones de salida de la consola en cualquier parte de su programa de interfaz gráfica de usuario para la depuración o de otro propósitos.

Cuestiones relacionadas