¿Cómo mantener abierta la ventana de la consola en Visual C ++?

191

Estoy comenzando en Visual C ++ y me gustaría saber cómo mantener la ventana de la consola.

Por ejemplo, esta sería una aplicación típica de "hola mundo":

int _tmain(int argc, _TCHAR* argv[])
{
    cout << "Hello World";
    return 0;
}

¿Cuál es la línea que me falta?

Raúl Roa
fuente
Amruth A. Pillai su código no muestra "presione cualquier tecla para continuar" gracias
Puede imprimirlo usted mismo con una simple llamada std :: cout.
Raúl Roa
55
La desventaja de todas las soluciones propuestas es que ninguna de ellas funciona con la depuración (Ctrl + F5 falla aquí) y cuando la aplicación se detiene inesperadamente (todos los puntos de interrupción o lecturas de stdin en el retorno principal fallan aquí). Lo que me encantaría ver es una ventana de consola en IDE como Eclipse y otros IDE. Simplemente siguen mostrando la salida a stdout / stderr después de que el programa ha finalizado.
dr. Sybren
@sybren La respuesta aceptada funciona con CTRL + F5, y ¿por qué querría una solución que funcione con la depuración (F5)? Seguramente el objetivo de la depuración es ... ¿depurar? ¿Cuál es el beneficio de tener una consola en pausa después de la finalización del programa, en una sesión de depuración?
JBentley
2
@JBentley Eclipse y otros IDEs le permiten leer la salida de su programa incluso después de que finalizó el proceso. ¿Seguramente ve el beneficio adicional, especialmente cuando trata de encontrar un error? Además, un punto de interrupción solo funciona cuando sabe dónde está terminando el programa, lo que puede ser difícil de determinar cuando la salida desaparece de su pantalla.
dr. Sybren

Respuestas:

389

Comience el proyecto con en Ctrl+F5lugar de solo F5.

La ventana de la consola ahora permanecerá abierta con el Press any key to continue . . .mensaje después de que el programa salga.

Tenga en cuenta que esto requiere la Console (/SUBSYSTEM:CONSOLE)opción del vinculador, que puede habilitar de la siguiente manera:

  1. Abra su proyecto y vaya al Explorador de soluciones. Si me sigue en K&R, su "Solución" será 'hola' con 1 proyecto debajo, también 'hola' en negrita.
  2. Haga clic derecho en 'hola "(o el nombre de su proyecto).
  3. Elija "Propiedades" en el menú contextual.
  4. Elija Propiedades de configuración> Vinculador> Sistema.
  5. Para la propiedad "Subsistema" en el panel de la derecha, haga clic en el cuadro desplegable en la columna de la derecha.
  6. Elija "Consola (/ SUBSISTEMA: CONSOLA)"
  7. Haga clic en Aplicar, espere a que termine de hacer lo que sea que haga, luego haga clic en Aceptar. (Si "Aplicar" está atenuado, elija otra opción de subsistema, haga clic en Aplicar, luego regrese y aplique la opción de consola. Mi experiencia es que OK por sí solo no funcionará).

CTRL-F5 y las sugerencias del subsistema funcionan juntas; No son opciones separadas.

(Cortesía de DJMorreTX de http://social.msdn.microsoft.com/Forums/en-US/vcprerelease/thread/21073093-516c-49d2-81c7-d960f6dc2ac6 )

Zoidberg
fuente
36
Esto ejecuta el programa sin depurar; Es mejor tener una solución que funcione tanto en modo de depuración como en modo de ejecución normal.
ス ー パ ー フ ァ ミ コ ン
3
Para cualquiera que no pueda lograr que esta solución funcione en un proyecto de archivo MAKE, esto se debe a un error en Visual Studio. Acabo de publicar una respuesta con la solución.
JBentley
1
Puede confirmar! Tenía una aplicación de consola que no funcionaba, hizo esto y funcionó. No necesita cambiar su código con cin.get(),getchar(), system("pause")o cualquier otra basura. Cambiar esto funciona.
Callat
Ctrl + F5 significa 'Iniciar sin depurar'. Por lo tanto, no puede usar esto al depurar. Simplemente agregue system("pause");al final de su código. Tiene sentido y funciona bien.
Milad
41

La forma estándar es cin.get()antes de su declaración de devolución.

int _tmain(int argc, _TCHAR* argv[])
{
    cout << "Hello World";
    cin.get();
    return 0;
}
Gordon Wilson
fuente
44
Sé que, dado que el programa ya está utilizando cout, ya se ha solucionado, pero creo que vale la pena mencionar que deberá #incluir <iostream> y usar el espacio de nombres std: std :: cin.get () .
Brian
77
Esto funciona, pero las teclas Ctrl + F5 es mucho mejor, especialmente al trazar la destrucción objeto global, etc.
ternario
8
-1 para _tmain. Votaría otro -1 para el cin.get()lugar de colocar un punto de interrupción para F5 o usar Ctrl F5. Pero solo se me permite un voto negativo.
Saludos y hth. - Alf
8
@Cheers: ¿Qué tiene de malo _tmain? Esa es la forma estándar de escribir una aplicación de Windows dirigida al subsistema Consola. Desviarse de ese estándar es lo que sería una mala práctica. Claramente, nadie está hablando de código portátil aquí; la pregunta dice Visual C ++ y _tmaines la firma que aparece en el código de muestra. Es hora de abandonar esta religión. Windows es "no estándar" de forma predeterminada, y existen muy buenas razones para seguir sus estándares.
Cody Gray
8
@CodyGray: Mi voto negativo _tmaines porque es totalmente innecesario no estándar (el estándar internacional de C ++ requiere una simple main), y porque utiliza el Tesquema macro de Microsoft , que es una complicación innecesaria y una palabrería para admitir Windows 9x. Si siente que desviarse del estándar es una mala práctica, entonces no debe usarlo tmain. No hay buenas razones para usar tmain, excepto para curricán o, para profesionales, para mostrar la incompetencia total.
Saludos y hth. - Alf
24

Pon un punto de interrupción en la returnlínea.

Lo estás ejecutando en el depurador, ¿verdad?

Sam Harwell
fuente
15
la mayoría de las veces es difícil ya que puede haber múltiples puntos de salida dentro del programa
volzotan
Es posible que el programa no se inicie debido a la falta de DLL y nunca llegue a ese punto de interrupción
Michael
17

Otra opción es usar

#include <process.h>
system("pause");

Aunque esto no es muy portátil porque solo funcionará en Windows, pero imprimirá automáticamente

Pulse cualquier tecla para continuar...

Marcos Marin
fuente
1
system ("pausa") Mantendrá su procesador en funcionamiento, no debe usarse. Use un cin.get () o equivalente.
Krythic
systemse declara en <stdlib.h>.
melpomene
@Krythic Acabo de probarlo y no se comió 100% de CPU El uso de mi procesador fue del 0% al 1% todo el tiempo. No puede reproducirse.
melpomene
system ("pausa") llamará al comando "pausa" en cmd, que NO usa la CPU todo el tiempo. Es equivalente a _getche () esencialmente.
Paul Stelian
7

Para los proyectos de archivo MAKE, la solución aceptada falla debido a un error en Visual Studio (que está presente al menos hasta la versión 2012; aún no he probado 2013). Este error se detalla aquí .

Para que la consola se detenga después de la finalización del programa en un proyecto de archivo MAKE, realice estos pasos (esto puede diferir para versiones distintas de 2010 - 2012):

1) Pase /SUBSYSTEM:CONSOLEal enlazador. - EDITAR : ver más abajo.

2) Abra su archivo de proyecto (.vcxproj) en un editor de texto.

3) Dentro de la <project>etiqueta raíz , inserte lo siguiente:

<ItemDefinitionGroup>
  <Link>
    <SubSystem>Console</SubSystem>
  </Link>
</ItemDefinitionGroup>

4) Vuelva a cargar el proyecto en su solución.

5) Ejecute el programa sin depurar (CTRL + F5).

EDITAR:

Según mi comentario a continuación, configurar la opción del vinculador /SUBSYSTEM:CONSOLEes realmente irrelevante para proyectos de archivo MAKE (y no necesariamente es posible, si está utilizando un compilador que no sea MSVC). Lo único que importa es que la configuración se agrega al archivo .vcxproj, como se indica en el paso 3 anterior.

JBentley
fuente
Nunca he oído hablar de ese paso 3 antes. ¿Estás seguro de que es obligatorio y funciona?
Mooing Duck
@mooingduck Sí, y después de mis comentarios sobre su respuesta aquí , ahora descubrí que pasar /SUBSYSTEM:CONSOLEal enlazador es realmente irrelevante: el paso 3 es lo único que importa. Tenga en cuenta que mi respuesta se relaciona con los proyectos de archivos MAKE: en un proyecto de archivos MAKE, el IDE no tiene forma de saber qué está pasando al vinculador (es posible que ni siquiera esté utilizando un compilador que tiene una /SUBSYSTEM:CONSOLEopción), y es el proyecto en sí mismo, que realiza un seguimiento de si está destinado o no a ser un programa de consola. Editaré mi respuesta en consecuencia.
JBentley
1
@mooingduck También puedo confirmar que uso esta solución yo mismo en un proyecto makefile, con SCons como sistema de compilación y MSVC y MinGW como compiladores. No hay otra manera que conozca para hacer que el IDE pause la consola después de la finalización en modo sin depuración.
JBentley
1
@chuckleplant Me temo que no, mi flujo de trabajo fue al revés, llamando a SCons desde VS. Inicialmente, creé manualmente mis proyectos VS makefile para que pasaran las variables de configuración a mi script SCons (por ejemplo, 32/64 bit, nombre del compilador, lanzamiento / depuración), que luego manejó el resto de la lógica. En esa configuración no había necesidad de que los archivos del proyecto cambiaran, por lo que no utilicé ninguna función de generación automática de SCons. Desde entonces he cambiado a Linux, así que ya no uso VS. Dado que es un error de VS, puede valer la pena enviar una solicitud de función a SCons para que se encargue del paso adicional requerido.
JBentley
1
Alternativamente, puede incluir un código Python en su script SCons para hacerlo usted mismo cada vez que se genera un archivo de proyecto. Creo que los archivos de proyecto VS cumplen con el estándar XML, por lo que debería ser bastante fácil agregar los elementos que faltan, y solo debería requerir unas pocas líneas de código. Sugeriría comenzar aquí (para Python 2.x) o aquí (3.x). Esta respuesta también puede ser de interés.
JBentley
4

Puede usar cin.get();o cin.ignore();justo antes de su declaración de devolución para evitar que la ventana de la consola se cierre.

CMS
fuente
4

solo ponga un punto de interrupción en el último soporte rizado de main.

    int main () {
       //...your code...
       return 0;
    } //<- breakpoint here

funciona para mí, no es necesario ejecutarlo sin depurarlo. También ejecuta destructores antes de llegar al punto de interrupción para que pueda verificar cualquier mensaje impreso en estos destructores si tiene alguno.

Juan Castaño
fuente
3

Simplemente agregue un punto de interrupción al corchete de cierre de su _tmainmétodo. Esta es la forma más fácil, además de que no tiene que agregar código para depurar.

Odys
fuente
2

Coloque un punto de interrupción en la llave final de main(). Se disparará incluso con múltiples returndeclaraciones. El único inconveniente es que una llamada aexit() no será capturada.

Si no está depurando, siga los consejos de la respuesta de Zoidberg y comience su programa con Ctrl+ en F5lugar de solo F5.

Chad
fuente
2

Mis 2 centavos:

Opción 1: agregar un punto de interrupción al final de main()

Opción 2: agregue este código, justo antes de return 0;:

std::cout << "Press ENTER to continue..."; //So the User knows what to do
std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');

Necesitas incluir <iomanip>parastd::numeric_limits

Arnav Borborah
fuente
2

simplemente agregue el sistema ("pausa") al final del código antes de devolver 0 como este

#include <stdlib.h>

int main()
{
    //some code goes here
    system("pause")
    return 0;
}
melpomene
fuente
2
int main()
{
    //...
    getchar();
    return 0;
}
va a visitar
fuente
2

cin.get()O system("PAUSE"). No he escuchado que puedas usarreturn(0);

Udhav Sarvaiya
fuente
1

Incluyo #include <conio.h>y luego, agrego getch();justo antes de la return 0;línea. Eso es lo que aprendí en la escuela de todos modos. Los métodos mencionados anteriormente aquí son bastante diferentes, veo.

Amruth Pillai
fuente
2
-1: Aparte del hecho de que hacer que el programa se detenga, generalmente es la solución incorrecta (ya que en la mayoría de los casos ese no es el comportamiento que desea que tenga su binario liberado), conio.h no es estándar , está desactualizado y es un C encabezado, no C ++! Desafortunadamente, hay muchas malas prácticas de programación que se enseñan en las escuelas.
JBentley
Uno espera que esto se use solo durante las pruebas, no es algo que mantendría en la versión final. Si está codificando para Windows, ¿cuál es el problema con #include <conio.h> / _getch () ;? Se escribe más rápido que cin.get (), no requiere presionar 2 teclas (al menos un carácter + enter), y no funciona solo en depuración o solo en modo de liberación. ¿Qué pasa entonces?
Barnack
1

Tuve el mismo problema Estoy usando _getch()justo antes de la declaración de devolución. Funciona.

Martín
fuente
Es posible que desee agregar ejemplos y explicaciones a su código, especialmente para una pregunta formulada / respondida hace tanto tiempo. Además, su respuesta es funcionalmente idéntica a varias respuestas anteriores y utiliza la misma llamada que otra respuesta existente.
Clockwork-Muse
0

(Algunas opciones se pueden llamar con diferentes nombres. No uso la versión en inglés)

Tuve el mismo problema, cuando creé proyectos con la opción "proyecto vacío", Crear proyecto como "Aplicación de consola Win32" en lugar de "proyecto vacío". En el cuadro de diálogo que aparece ahora, presiona "continuar" y luego puede marcar la opción "proyecto vacío" y presionar confirmar. Después de eso, CTRL + F5 abrirá una consola que no se cierra automáticamente.

Blechdose
fuente
0

Yo tuve el mismo problema; En mi aplicación hay múltiples puntos de salida () y no había forma de saber exactamente dónde sale, entonces descubrí esto:

atexit(system("pause"));

o

atexit(cin.get());

De esta manera, se detendrá sin importar dónde salgamos del programa.

Charaf Errachidi
fuente
Ninguno de esos son llamadas válidas a atexit. atexittoma un puntero de función, no un entero.
melpomene
0

Otra opción:

#ifdef _WIN32
#define MAINRET system("pause");return 0
#else
#define MAINRET return 0
#endif

En principal:

int main(int argc, char* argv[]) {
    MAINRET;
}
chen_767
fuente
0

En realidad, la solución real es la selección de la plantilla del proyecto en sí. DEBE seleccionar la aplicación de consola Win32 en VS anteriores, o complete primero el nombre del proyecto y luego haga doble clic en el asistente de escritorio de Windows y luego seleccione la aplicación de consola Win32. Luego seleccione proyecto vacío en este punto. Esto permite lo que realmente quería el interrogador original sin agregar un punto de detención adicional y un código de retención. Pasé por este problema también. La respuesta también está en el sitio de MSDN.

usuario9416431
fuente
0

Aquí hay una manera de mantener abierta la ventana de comandos, independientemente de cómo se detenga la ejecución sin modificar ningún código:

En Visual Studio, abra las páginas de propiedades del proyecto -> Depuración .

Para Comando , ingrese$(ComSpec)

Para Argumentos de comando , ingrese/k $(TargetPath) . Agregue cualquier argumento a su propia aplicación.

Ahora F5 o Ctrl-F5 ejecuta Windows / System32 / cmd.exe en una nueva ventana y / k asegura que el símbolo del sistema permanezca abierto después de que se complete la ejecución.

La desventaja es que la ejecución no se detendrá en los puntos de interrupción.

Jonathan Lidbeck
fuente
0

Como algunos ya han señalado, la solución de Zoidbergs no adjunta el depurador, que es algo que generalmente no desea.

La mejor opción es configurar su VS en consecuencia (a partir de VS 2017 en adelante), vaya a Herramientas> Opciones> Depuración> General. Allí desmarca "Cerrar automáticamente la consola cuando se detiene la depuración" (en la parte inferior), que probablemente esté marcada en su caso.

iko79
fuente
-1

solo puedes poner keep_window_open (); antes del regreso aquí hay un ejemplo

int main()
{
    cout<<"hello world!\n";
    keep_window_open ();
    return 0;
}
Sifis Babionitakis
fuente
2
¿De dónde viene keep_window_open (), por ejemplo, qué archivo de encabezado y biblioteca?
Tom Goodfellow
es de este std_lib_facilities.h pero la mayoría de las veces lo tienes incluido
Sifis Babionitakis