sistema ("pausa"); - Por que isso está errado?

131

Aqui está uma pergunta que eu não entendo direito:

O comando system("pause");é ensinado aos novos programadores como uma maneira de pausar um programa e aguardar a entrada do teclado continuar. No entanto, muitos programadores veteranos parecem desaprovados como algo que não deve ser feito em graus variados.

Algumas pessoas dizem que é bom usar. Alguns dizem que só deve ser usado quando você está trancado em seu quarto e ninguém está assistindo. Alguns dizem que eles pessoalmente vão à sua casa e o matam se você a usar.

Eu próprio sou um novo programador sem formação formal em programação. Eu uso porque fui ensinado a usá-lo. O que não entendo é que, se não é algo para ser usado, então por que fui ensinado a usá-lo? Ou, por outro lado, não é realmente tão ruim assim?

Quais são seus pensamentos sobre este assunto?

Faken
fonte
related: stackoverflow.com/questions/900666/...
Gordon Gustafson
5
Aparentemente, as pessoas gostam de fazer chamadas para serem realmente eficientes. Em outras palavras, "Apresse-se e pare!"
18711 Lee Louviere
63
Você foi ensinado porque geralmente os professores são maus programadores
que
Por favor, leia este conselho ao fazer boas perguntas: [ Como fazer ], [Escrevendo a pergunta perfeita ].
Adi Inbar
9
@wich completamente absurdo.
Michael Chourdakis

Respostas:

85

Ele é desaprovado porque é um hack específico da plataforma que não tem nada a ver com o aprendizado de programação, mas para contornar um recurso do IDE / OS - a janela do console iniciada no Visual Studio fecha quando o programa termina a execução, e assim o novo usuário não consegue ver a saída de seu novo programa.

O desvio no sistema ("pausa") executa o programa "pausa" da linha de comando do Windows e aguarda o término antes de continuar a execução do programa - a janela do console permanece aberta para que você possa ler a saída.

Uma idéia melhor seria colocar um ponto de interrupção no final e depurá-lo, mas isso novamente tem problemas.

ravuya
fonte
6
O Visual Studio pode executar o programa em dois modos: com ou sem depuração. Quando executado no modo de depuração, ele pára no primeiro ponto de interrupção. Se você não tiver um definido, ele executará o programa e fechará o console. Portanto, se você deseja que o programa do console pare, basta definir um ponto de interrupção ou, melhor ainda, executá-lo sem depurar! Isso executará o programa e interromperá o console.
Ivan Mesic
Este não é apenas um recurso do Visual Studio - se você executar um programa de console do Windows (por exemplo, ao contrário de carregar um prompt de comando e executá-lo a partir daí), ele também será fechado quando terminar a execução.
JBentley
2
−1 Re “a janela do console iniciada no Visual Studio fecha quando o programa termina a execução”, não, apenas para quando o programa é executado no depurador. Re “executa o programa de" pausa "da linha de comando do Windows, não existe ( pauseexiste um comando interno cmd.exe). A lista de melhores idéias também está em falta.
Saúde e hth. - Alf
Acho que essa resposta é a única que aborda o aspecto de que essa é uma solução alternativa. Ele soluciona o comportamento de um ambiente de execução específico que fecha uma janela do terminal antes que você possa ler a saída do programa. O que você deve fazer é consertar esse ambiente. Se isso não puder ser feito, use esta solução alternativa, possivelmente apenas se IsDebuggerPresent()retornar true e documente essa solução alternativa ("por que esse código está aqui?").
Ulrich Eckhardt
43

É lento. Depende da plataforma. É inseguro.

Primeiro: o que faz. Chamar "sistema" é literalmente como digitar um comando no prompt de comando do Windows. Há uma tonelada de configurações e desmontagens para o seu aplicativo fazer essa ligação - e a sobrecarga é simplesmente ridícula.

E se um programa chamado "pausa" fosse colocado no PATH do usuário? Apenas chamar o sistema ("pausa") garante apenas que um programa chamado "pausa" seja executado (espero que você não tenha o seu executável chamado "pausa"!)

Simplesmente escreva sua própria função "Pause ()" que usa _getch. OK, claro, _getch também depende da plataforma (observe: está definido em "conio.h") - mas é muito melhor do que system()se você estiver desenvolvendo no Windows e tem o mesmo efeito (embora seja sua responsabilidade fornecer o texto com cout ou mais).

Basicamente: por que apresentar tantos problemas em potencial quando você pode simplesmente adicionar duas linhas de código e uma incluir e obter um mecanismo muito mais flexível?

Jonathan Leffler
fonte
61
Para alguém que se queixa da dependência da plataforma, parece estranho sugerir _getch, especialmente quando o C ++ padrão fornece getchar.
precisa
33
i sentir alguma ironia no cálculo sobrecarga para a interacção com um humano)
ShPavel
1
@ Spagpants: Talvez você não entenda a diferença entre receber informações de um ser humano e gerar imagens e sons em um ser humano.
yzt
1
@ Cheersandhth.-Alf - Hum? Quando escrevi isso, há oito anos, eu havia acabado de depurar um problema causado por 'system ("pause")' porque o nome do executável do projeto era chamado de "pause" e entrava em um loop infinito. Meu argumento ainda está de pé, não sei por que você está dizendo que eu estava incorreta.
2
@paxdiablo getchar requer uma entrada e, em seguida, pressionando enter. _getch requer apenas um pressionamento de tecla, independentemente da chave. Para emular _getch no linux, você precisa de 5 a 6 linhas de código para alterar o modo do console e, em seguida, voltar ao padrão. Não é o mesmo, faz coisas diferentes. getchar não é um substituto para _getch.
Barnack
29
  • lento: ele precisa percorrer muitos códigos desnecessários do Windows e um programa separado para uma operação simples
  • não portátil: depende do programa de pausa
  • Não é um bom estilo: fazer uma chamada ao sistema só deve ser feito quando realmente necessário
  • mais digitação: Sistema ("pausa") é maior que getchar ()

um simples getchar () deve funcionar perfeitamente.

Gavin H
fonte
26

Usar não system("pause");é uma boa prática ™ porque

  • É completamente desnecessário .
    Para manter a janela do console do programa aberta no final, quando você o executa no Visual Studio, use Ctrl+ F5para executá-lo sem depuração, ou coloque um ponto de interrupção no último colchete direito }de main. Portanto, não há problema no Visual Studio. E, claro, não há problema algum quando você o executa na linha de comando.

  • É problemático e irritante
    quando você executa o programa na linha de comando. Para execução interativa, você precisa pressionar uma tecla no final, sem nenhum objetivo. E para uso na automação de alguma tarefa que pauseé muito indesejada!

  • Não é portátil.
    O Unix-land não possui pausecomando padrão .

O pausecomando é um cmd.execomando interno e não pode ser substituído, como é reivindicado erroneamente em pelo menos uma outra resposta. Ou seja, não é um risco à segurança, e a alegação de que os programas AV o diagnosticam como tal é tão dúbia quanto a alegação de substituir o comando (afinal, um programa em C ++ systemestá em posição de fazer tudo o que o intérprete de comando pode fazer, e Mais). Além disso, embora essa maneira de pausar seja extremamente ineficiente pelos padrões usuais da programação em C ++, isso não importa no final do programa de um novato.

Portanto, as alegações na horda de respostas anteriores não estão corretas, e o principal motivo para você não usar system("pause") ou qualquer outro comando de espera no final do seu mainé o primeiro ponto acima: é completamente desnecessário, não serve para nada , é apenas muito bobo.

Felicidades e hth. - Alf
fonte
1
Às vezes, uma prática ungood ™ é necessário para testes rápidos .... o que chamamos de "rápida e suja"
Michael Haephrati
22

Em resumo, ele precisa pausar a execução dos programas e fazer uma chamada do sistema e alocar recursos desnecessários quando você pode usar algo tão simples quanto o cin.get (). As pessoas usam o System ("PAUSE") porque desejam que o programa aguarde até pressionar Enter para poder ver sua saída. Se você deseja que um programa aguarde entrada, há funções integradas para as que também são multiplataforma e menos exigentes.

Mais explicações neste artigo.

John T
fonte
Uau, você de novo! você mora aqui? lol De qualquer forma, obrigado, vou fazer algumas leituras. Enquanto isso, quais são seus pensamentos sobre esse assunto?
Faken
Eu tinha essa mesma pergunta quando comecei o C, há alguns anos, e fui apontado para o mesmo artigo. Eu uso getchar () pessoalmente.
John T
Ho wow ... Eu não fiz C ++ por um tempo, mas sim .. há definitivamente melhores formas de alcançar os mesmos resultados
Newtopian
16

Você pode usar std::cin.get()em 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;
}

Além disso, system('pause')é lento, e inclui um arquivo que você provavelmente não precisa: stdlib.h. Depende da plataforma e, na verdade, chama um sistema operacional 'virtual'.

Gavriel Feria
fonte
3
Fui ensinado a usar System("pause")em um curso de programação do primeiro ano, mas queria poder executar meus programas no meu Mac, então tive que aprender cin.get().
Davidales 14/10/2014
10

Porque não é portátil.

pause

é um programa somente para Windows / DOS, portanto esse código não será executado no Linux. Além disso, systemnão é geralmente considerado como uma boa maneira de chamar outro programa - é geralmente melhor usar CreateProcessou forkou algo similar.

a_m0d
fonte
4

Conforme listado nas outras respostas, há muitos motivos para você evitar isso. Tudo se resume a uma razão que faz o resto discutível. oSystem() função é inerentemente insegura / não confiável e não deve ser introduzida em um programa, a menos que seja necessário.

Para uma tarefa de estudante, essa condição nunca foi atendida e, por esse motivo, eu falharia em uma tarefa sem nem mesmo executar o programa se uma chamada para esse método estivesse presente. (Isso ficou claro desde o início.)

Sam Harwell
fonte
4

Para mim, não faz sentido, em geral, esperar antes de sair sem motivo. Um programa que fez seu trabalho deve terminar e entregar seus recursos de volta ao seu criador.

Também não se espera silenciosamente em um canto escuro depois de um dia de trabalho, à espera de alguém dar uma gorjeta no ombro.

Sebastian Mach
fonte
7
Esta é uma resposta boba. Parte de um programa "realizando seu trabalho" está exibindo os resultados de seu trabalho para o usuário. Portanto, não deve terminar até que o usuário notifique que ele terminou. Um programa que desaparece da tela do usuário um nanossegundo após exibir seus resultados é inútil.
JBentley
1
@JBentley: Eu falei sobre a situação depois de exibir os resultados, se houver. Para exibir resultados, existem padrões apropriados, como sinais, interrupções, cronômetros, retorno no seu terminal, arquivos. system("pause")por si só não exibe nada. Um programa de interface de linha de comando que não é chamado a partir da linha de comando e fecha muito cedo é chamado incorretamente e com as opções erradas, e usar system("pause")para contornar um programa chamado incorretamente não é realmente a coisa certa a fazer.
Sebastian Mach
1
Quero dizer, imaginem cat, less, vi, OpenOffice, Mathematica, GNU Octave, o que se usaria system("pause")? Isso seria chato.
Sebastian Mach
2
Sim, isso seria irritante, mas agora você está falando especificamente sobre os problemas de system("pause"), enquanto sua resposta fala sobre "espere antes de sair", que é um conceito muito mais generalizado. Muitos dos exemplos que você deu de fato "esperam antes de sair", até que o usuário informe ao programa que ele deseja que ele saia. Concordo que system("pause")não é uma boa maneira de conseguir isso e que existem soluções melhores, mas não é isso que sua resposta diz.
precisa saber é o seguinte
1
@ JBentley Oh, com certeza: se um atraso / espera / prompt fizer parte da semântica do programa, vá pauseembora!
Lightness Races em órbita
3
system("pause");  

está errado porque faz parte da API do Windows e, portanto, não funciona em outros sistemas operacionais.

Você deve tentar usar apenas objetos da biblioteca padrão C ++. Uma solução melhor será escrever:

cin.get();
return 0;

Mas também causará problemas se você tiver outros cins no seu código. Porque depois de cada cin, você vai tocar em um Enterou \nque é um caractere espaço em branco. cinignora esse caractere e o deixa na zona de buffer, mas cin.get()obtém esse caractere restante. Portanto, o controle do programa atinge a linha return 0e o console é fechado antes de permitir que você veja os resultados.
Para resolver isso, escrevemos o código da seguinte maneira:

cin.ignore();  
cin.get();  
return 0;
Sepideh Abadpour
fonte
Isso é um pouco enganador. system()é padrão e não específico para o MS Windows. No entanto, o pausecomando shell é uma herança do DOS e normalmente só é encontrado lá.
Ulrich Eckhardt
1

Aqui está um motivo pelo qual você não deve usá-lo: ele vai irritar a maioria dos programas antivírus em execução no Windows se você estiver passando o programa para outra máquina porque é uma ameaça à segurança. Mesmo se o seu programa consistir apenas em um cout << "hello world\n"; system("pause"); recurso É pesado e o programa obtiver acesso ao comando cmd, que os antivírus consideram uma ameaça.

Andreas DM
fonte
-1

os profissionais estão usando o sistema ("PAUSE"); enquanto a criação de pequenas partes do seu programa é para depuração você mesmo. se você o usar para obter resultados de variáveis ​​antes, durante e após cada processo que estiver usando, para garantir que eles estejam funcionando corretamente.

Após testar e movê-lo em pleno andamento com o restante da solução, você deve remover essas linhas. é realmente bom ao testar um algoritmo definido pelo usuário e garantir que você esteja fazendo as coisas na ordem correta para obter os resultados desejados.

De maneira alguma você deseja usá-lo em um aplicativo após testá-lo e garantir que está funcionando corretamente. No entanto, permite acompanhar tudo o que está acontecendo à medida que acontece. Não use para aplicativos de usuário final.

Ninguém em particular
fonte
-3

É tudo uma questão de estilo. É útil para depuração, mas, caso contrário, não deve ser usado na versão final do programa. Realmente não importa no problema da memória, porque tenho certeza de que aqueles que inventaram o sistema ("pausa") estavam prevendo que ele seria usado com frequência. Em outra perspectiva, os computadores ficam limitados à memória por todo o resto que usamos no computador, e isso não representa uma ameaça direta, como a alocação dinâmica de memória; portanto, eu o recomendaria para a depuração de código, mas nada mais.

Jason A.
fonte
6
Realmente não importa na questão da memória, porque tenho certeza de que os caras que inventaram o sistema ("pausa") estavam prevendo que ele seria usado com frequência, na verdade não faz nenhum sentido. Ninguém "inventou" isso, pausefoi projetado para uso em programas em lote do DOS, nunca foi planejado para ser usado de uma maneira como esta. Além disso, havia alternativas muito melhores antes que alguém fosse louco o suficiente para digitar a frase system("pause");.
que