sistema ("pausa"); - ¿Por qué está mal?

131

Aquí hay una pregunta que no entiendo del todo:

El comando system("pause");se enseña a los nuevos programadores como una forma de pausar un programa y esperar a que continúe la entrada del teclado. Sin embargo, parece ser mal visto por muchos programadores veteranos como algo que no debe hacerse en diversos grados.

Algunas personas dicen que está bien usarlo. Algunos dicen que solo debe usarse cuando está encerrado en su habitación y nadie lo está mirando. Algunos dicen que vendrán personalmente a su casa y lo matarán si lo usa.

Yo mismo soy un nuevo programador sin entrenamiento formal en programación. Lo uso porque me enseñaron a usarlo. Lo que no entiendo es que si no es algo para usar, ¿por qué me enseñaron a usarlo? O, por otro lado, ¿no es realmente tan malo después de todo?

¿Que piensas de este tema?

Falso
fuente
relacionado: stackoverflow.com/questions/900666/…
Gordon Gustafson
55
Aparentemente, a las personas les gusta que sus llamados a pausar sean realmente eficientes. En otras palabras, "¡Date prisa y para!"
Lee Louviere
63
Te lo enseñaron porque, en general, los profesores son malos programadores
que el
Lea este consejo sobre cómo hacer buenas preguntas: [ Cómo hacer ], [Escribir la pregunta perfecta ].
Adi Inbar el
9
@wich completamente sin sentido.
Michael Chourdakis

Respuestas:

85

Está mal visto porque es un truco específico de la plataforma que no tiene nada que ver con el aprendizaje real de la programación, sino que evita una característica del IDE / OS: la ventana de la consola lanzada desde Visual Studio se cierra cuando el programa ha finalizado la ejecución, y así el nuevo usuario no puede ver la salida de su nuevo programa.

Bodging in System ("pausa") ejecuta el programa "pausa" de la línea de comandos de Windows y espera a que termine antes de continuar la ejecución del programa; la ventana de la consola permanece abierta para que pueda leer la salida.

Una mejor idea sería poner un punto de interrupción al final y depurarlo, pero eso nuevamente tiene problemas.

ravuya
fuente
66
Visual Studio puede ejecutar el programa en dos modos: con o sin depuración. Cuando se ejecuta en modo de depuración, se detendrá en el primer punto de interrupción. Si no tiene uno definido, ejecutará el programa y cerrará la consola. Por lo tanto, si desea que el programa de la consola se detenga, ¡simplemente establezca un punto de interrupción o, mejor aún, ejecútelo sin depurarlo! Eso ejecutará el programa y detendrá la consola.
Ivan Mesic
Esta no es solo una característica de Visual Studio: si ejecuta un programa de consola desde Windows (es decir, en lugar de cargar un símbolo del sistema y ejecutarlo desde allí), también se cerrará cuando haya finalizado la ejecución.
JBentley
2
−1 Re “la ventana de la consola iniciada desde Visual Studio se cierra cuando el programa ha finalizado la ejecución”, no, solo para cuando el programa se ejecuta en el depurador. Re "ejecuta el programa de" pausa "de la línea de comandos de Windows", no hay tal ( pausees un comando interno en cmd.exe). La lista de mejores ideas también es muy escasa.
Saludos y hth. - Alf
Creo que esta respuesta es la única que toca el aspecto de que esta es una solución alternativa. Funciona alrededor del comportamiento de un entorno de ejecución específico que cierra una ventana de terminal antes de que pueda leer la salida del programa. Lo que debes hacer es arreglar ese entorno. Si eso no se puede hacer, use esta solución alternativa, posiblemente solo si IsDebuggerPresent()devuelve verdadero y documente esta solución adecuada ("¿por qué está este código aquí?").
Ulrich Eckhardt
43

Es lento. Depende de la plataforma. Es inseguro

Primero: lo que hace. Llamar "sistema" es literalmente como escribir un comando en el símbolo del sistema de Windows. Hay una tonelada de configuración y desmontaje para que su aplicación realice dicha llamada, y los gastos generales son simplemente ridículos.

¿Qué pasa si un programa llamado "pausa" se colocó en la RUTA del usuario? Solo llamar al sistema ("pausa") solo garantiza que se ejecute un programa llamado "pausa" (¡espero que no tenga su ejecutable llamado "pausa"!)

Simplemente escriba su propia función "Pause ()" que use _getch. OK, claro, _getch también depende de la plataforma (nota: se define en "conio.h"), pero es mucho mejor que system()si está desarrollando en Windows y tiene el mismo efecto (aunque es su responsabilidad proporcionar el texto con cout más o menos).

Básicamente: ¿por qué presentar tantos problemas potenciales cuando simplemente puede agregar dos líneas de código y una incluir y obtener un mecanismo mucho más flexible?

Jonathan Leffler
fuente
61
Para alguien que se queja de la dependencia de la plataforma, parece extraño sugerir _getch, especialmente cuando proporciona C ++ estándar getchar.
paxdiablo
33
siento cierta ironía al calcular los gastos generales para la interacción con un humano)
ShPavel
1
@Spagpants: Quizás no entiendes la diferencia entre recibir información de un humano y generar imágenes y sonidos en un humano.
yzt
1
@ Cheersandhth.-Alf - ¿Hm? Cuando escribí esto, hace 8 años, acababa de terminar de depurar un problema causado por 'sistema ("pausa")' porque el nombre ejecutable del proyecto se llamaba "pausa" y entraría en un bucle infinito. Mi punto sigue en pie, no estoy seguro de por qué estás diciendo que era incorrecto.
2
@paxdiablo getchar requiere una entrada y luego presionar enter. _getch solo requiere presionar una tecla, sin importar qué tecla sea. Para emular _getch en Linux, necesita 5-6 líneas de código para cambiar el modo de consola y luego volver a cambiarlo al predeterminado. No es lo mismo, hace cosas diferentes. getchar no es un reemplazo para _getch.
Barnack
29
  • lento: tiene que saltar muchos códigos innecesarios de Windows y un programa separado para una operación simple
  • no portátil: depende del programa de pausa
  • no es un buen estilo: hacer una llamada al sistema solo debe hacerse cuando realmente sea necesario
  • más tipeo: el sistema ("pausa") es más largo que getchar ()

un simple getchar () debería funcionar bien.

Gavin H
fuente
26

Usar system("pause");es Ungood Practice ™ porque

  • Es completamente innecesario .
    Para mantener abierta la ventana de la consola del programa al final cuando lo ejecuta desde Visual Studio, use Ctrl+ F5para ejecutarlo sin depurar, o coloque un punto de interrupción en la última llave derecha }de main. Entonces, no hay problema en Visual Studio. Y, por supuesto, no hay ningún problema cuando lo ejecutas desde la línea de comandos.

  • Es problemático y molesto
    cuando ejecuta el programa desde la línea de comandos. Para la ejecución interactiva, debe presionar una tecla al final sin ningún propósito. ¡Y para su uso en la automatización de alguna tarea que pausees muy indeseable!

  • No es portátil
    Unix-land no tiene un pausecomando estándar .

El pausecomando es un cmd.execomando interno y no se puede anular, como se afirma erróneamente en al menos otra respuesta. Es decir, no es un riesgo de seguridad, y la afirmación de que los programas AV lo diagnostican como tal es tan dudosa como la afirmación de anular el comando (después de todo, un programa C ++ que invocasystem está en posición de hacer todo lo que el intérprete de comandos puede hacer, y más). Además, si bien esta forma de pausa es extremadamente ineficiente según los estándares habituales de programación en C ++, eso no importa en absoluto al final del programa de un novato.

Entonces, las afirmaciones en la horda de respuestas antes de esto no son correctas, y la razón principal por la que no debe usar system("pause") ni ningún otro comando de espera al final de su main, es el primer punto anterior: es completamente innecesario, no sirve para nada , es muy tonto.

Saludos y hth. - Alf
fuente
1
A veces se necesita un Ungood Practice ™ para pruebas rápidas ... lo que llamamos "rápido y sucio"
Michael Haephrati
22

En resumen, tiene que pausar la ejecución de los programas y hacer una llamada al sistema y asignar recursos innecesarios cuando podría estar usando algo tan simple como cin.get (). Las personas usan el sistema ("PAUSA") porque quieren que el programa espere hasta que presionen enter para poder ver su salida. Si desea que un programa espere la entrada, hay funciones integradas para eso que también son multiplataforma y menos exigentes.

Más explicaciones en este artículo.

John T
fuente
Wow, tu otra vez! ¿vive usted aquí? jajaja De todos modos, gracias, voy a leer un poco. Mientras tanto, ¿cuáles son SUS pensamientos sobre este asunto?
Faken
Tenía la misma pregunta cuando comencé a usar C hace unos años, y me señalaron el mismo artículo. Yo uso getchar () personalmente.
John T
Ho wow ... No he hecho C ++ por un tiempo pero sí ... definitivamente hay mejores maneras de lograr los mismos resultados
Newtopian
16

Puedes usar std::cin.get()desde iostream:

#include <iostream> // std::cout, std::cin
using namespace std;

int main() {
   do {
     cout << '\n' << "Press the Enter key to continue.";
   } while (cin.get() != '\n');

   return 0;
}

Además, system('pause')es lento, e incluye un archivo es probable que no necesita: stdlib.h. Depende de la plataforma, y ​​en realidad llama a un sistema operativo 'virtual'.

Gavriel Feria
fuente
3
Me enseñaron a usar System("pause")en un curso de programación de primer año, pero quería poder ejecutar mis programas en mi Mac, así que tuve que aprender cin.get().
daviewales
10

Porque no es portátil.

pause

es un programa solo para Windows / DOS, por lo que este código no se ejecutará en Linux. Por otra parte, systemno se considera generalmente como una muy buena manera de llamar a otro programa - por lo general es mejor usar CreateProcesso forko algo similar.

a_m0d
fuente
4

Como se enumera en las otras respuestas, hay muchas razones que puede encontrar para evitar esto. Todo se reduce a una razón que hace que el resto sea discutible. La System()función es inherentemente insegura / no confiable, y no debe introducirse en un programa a menos que sea necesario.

Para una tarea de estudiante, esta condición nunca se cumplió y, por esta razón, fallaría una tarea sin siquiera ejecutar el programa si hubiera una llamada a este método. (Esto quedó claro desde el principio).

Sam Harwell
fuente
4

Para mí no tiene sentido en general esperar antes de salir sin razón. Un programa que ha hecho su trabajo debería terminar y entregar sus recursos a su creador.

Tampoco uno espera en silencio en un rincón oscuro después de un día de trabajo, esperando que alguien le incline el hombro.

Sebastian Mach
fuente
77
Esta es una respuesta tonta. Parte de un programa que "hace su trabajo" es mostrar los resultados de su trabajo al usuario. Por lo tanto, no debe finalizar hasta que el usuario le notifique que ha terminado con él. Un programa que desaparece de la pantalla del usuario un nanosegundo después de mostrar sus resultados, es inútil.
JBentley
1
@JBentley: hablé sobre la situación después de mostrar los resultados, si los hubo. Para mostrar resultados, existen patrones apropiados, como señales, interrupciones, temporizadores, desplazamiento hacia atrás en su terminal, archivos. system("pause")en sí mismo no muestra nada. Un programa de interfaz de línea de comando que se invoca no desde la línea de comando y se cierra demasiado temprano se invoca incorrectamente y con las opciones incorrectas, y usar system("pause")para eludir un programa invocado incorrectamente realmente no es lo correcto.
Sebastian Mach
1
Me refiero, imagínese cat, less, vi, OpenOffice, Mathematica, GNU Octave, lo que si se usaría system("pause")? Eso sería molesto.
Sebastian Mach
2
Sí, eso sería molesto, pero ahora estás hablando específicamente de los problemas de system("pause"), mientras que tu respuesta habla de "esperar antes de salir", que es un concepto mucho más generalizado. De hecho, muchos de los ejemplos que dio "esperen antes de salir", hasta que el usuario informe al programa que desea que salga. Estoy de acuerdo en que system("pause")no es una buena manera de lograrlo y que hay mejores soluciones, pero eso no es lo que dice su respuesta.
JBentley
1
@JBentley Oh, absolutamente: si un retraso / espera / solicitud es parte de la semántica del programa, pause¡fuera!
Carreras de ligereza en órbita el
3
system("pause");  

está mal porque es parte de la API de Windows y, por lo tanto, no funcionará en otros sistemas operativos.

Debe intentar usar solo objetos de la biblioteca estándar de C ++. Una mejor solución será escribir:

cin.get();
return 0;

Pero también causará problemas si tiene otros cins en su código. Porque después de cada uno cin, tocarás un Entero \nque es un carácter de espacio en blanco. cinignora este carácter y lo deja en la zona de amortiguación, pero cin.get()obtiene este carácter restante. Entonces el control del programa llega a la línea return 0y la consola se cierra antes de permitirle ver los resultados.
Para resolver esto, escribimos el código de la siguiente manera:

cin.ignore();  
cin.get();  
return 0;
Sepideh Abadpour
fuente
Eso es un poco engañoso. system()es estándar y no es específico de MS Windows. Sin embargo, el pausecomando de shell es una herencia de DOS y normalmente solo se encuentra allí.
Ulrich Eckhardt
1

Aquí hay una razón por la que no debe usarlo: va a molestar a la mayoría de los programas antivirus que se ejecutan en Windows si está pasando el programa a otra máquina porque es una amenaza para la seguridad. Incluso si su programa solo consta de un cout << "hello world\n"; system("pause"); recurso simple de recursos pesados ​​y el programa obtiene acceso al comando cmd, que los antivirus ven como una amenaza.

Andreas DM
fuente
-1

los pro para usar el sistema ("PAUSA"); mientras crea pequeñas porciones de su programa es para depurarlo usted mismo. si lo utiliza para obtener resultados de variables antes, durante y después de cada proceso que está utilizando para asegurarse de que funcionan correctamente.

Después de probar y moverlo a pleno rendimiento con el resto de la solución, debe eliminar estas líneas. es realmente bueno al probar un algoritmo definido por el usuario y asegurarse de que está haciendo las cosas en el orden correcto para obtener los resultados que desea.

De ninguna manera quiere usar esto en una aplicación después de haberlo probado y asegurado que está funcionando correctamente. Sin embargo, le permite realizar un seguimiento de todo lo que sucede a medida que sucede. No lo use para aplicaciones de usuario final en absoluto.

Nadie en particular
fuente
-3

Todo es cuestión de estilo. Es útil para la depuración, pero de lo contrario no debería usarse en la versión final del programa. Realmente no importa el problema de la memoria porque estoy seguro de que aquellos que inventaron el sistema ("pausa") anticipaban que se usaría con frecuencia. En otra perspectiva, las computadoras se estrangulan en su memoria para todo lo demás que usamos en la computadora de todos modos y no representa una amenaza directa como la asignación de memoria dinámica, por lo que lo recomendaría para depurar código, pero nada más.

Jason A.
fuente
66
Realmente no importa el problema de la memoria porque estoy seguro de que aquellos que inventaron el sistema ("pausa") anticipaban que se usaría con frecuencia, realmente no tiene ningún sentido. Nadie "inventó" esto, pausefue diseñado para su uso en programas por lotes de DOS, nunca fue pensado para ser utilizado de esta manera. Además, había alternativas mucho mejores antes de que alguien estuviera lo suficientemente loco como para escribir la frase system("pause");.
que el