Sistema ( “pausa”); - Perché è sbagliato?


131

Ecco una domanda che non capisco bene:

Il comando system("pause");viene insegnato ai nuovi programmatori come un modo per mettere in pausa un programma e attendere che un input da tastiera continui. Tuttavia, sembra essere disapprovato da molti programmatori veterani come qualcosa che non dovrebbe essere fatto in varia misura.

Alcune persone dicono che va bene usare. Alcuni dicono che deve essere usato solo quando sei rinchiuso nella tua stanza e nessuno sta guardando. Alcuni dicono che verranno personalmente a casa tua e ti uccideranno se lo usi.

Io stesso sono un nuovo programmatore senza formazione formale di programmazione. Lo uso perché mi è stato insegnato a usarlo. Quello che non capisco è che se non è qualcosa da usare, perché mi è stato insegnato a usarlo? O, al contrario, non è davvero così male dopo tutto?

Cosa ne pensi di questo argomento?



5
Apparentemente alla gente piace che le loro chiamate si fermino per essere davvero efficienti. In altre parole, "Sbrigati e fermati!"
Lee Louviere,

63
Ti è stato insegnato perché generalmente gli insegnanti sono dei cattivi programmatori
che il

Si prega di leggere questo consiglio su come porre buone domande: [ Come porre ], [Scrivere la domanda perfetta ].
Adi Inbar,

9
@wich completamente senza senso.
Michael Chourdakis,

Risposte:


85

È malvisto perché è un hack specifico per la piattaforma che non ha nulla a che fare con l'apprendimento della programmazione, ma invece per aggirare una funzione dell'IDE / OS: la finestra della console avviata da Visual Studio si chiude quando il programma ha terminato l'esecuzione, e così il nuovo utente non riesce a vedere l'output del suo nuovo programma.

Bodging in System ("pause") esegue il programma "pause" della riga di comando di Windows e attende che termini prima di continuare l'esecuzione del programma - la finestra della console rimane aperta in modo da poter leggere l'output.

Un'idea migliore sarebbe quella di mettere un breakpoint alla fine e debug, ma questo ha di nuovo problemi.


6
Visual Studio può eseguire il programma in due modalità: con o senza debug. Quando eseguito in modalità debug, si fermerà al primo punto di interruzione. Se non ne hai uno definito, eseguirà il programma e chiuderà la console. Quindi, se vuoi che il programma della console si fermi, basta impostare un break-point o, ancora meglio, eseguirlo senza debug! Ciò eseguirà il programma e arresterà la console.
Ivan Mesic,

Questa non è solo una funzionalità di Visual Studio: se si esegue un programma console da Windows (ovvero invece di caricare un prompt dei comandi ed eseguirlo da lì), si chiuderà anche al termine dell'esecuzione.
JBentley,

2
−1 Ri "la finestra della console avviata da Visual Studio si chiude al termine dell'esecuzione del programma", no, solo per quando il programma viene eseguito nel debugger. Ri "esegue il programma" pausa "della riga di comando di Windows, no non esiste ( pauseè presente un comando interno cmd.exe). Anche l'elenco delle idee migliori è gravemente carente.
Saluti e hth. - Alf

Penso che questa risposta sia l'unica che tocca l'aspetto che questa è una soluzione alternativa. Funziona attorno al comportamento di un ambiente di esecuzione specifico che chiude una finestra del terminale prima di poter leggere l'output del programma. Quello che dovresti fare è riparare quell'ambiente. Se ciò non è possibile, utilizzare questa soluzione alternativa, possibilmente solo se IsDebuggerPresent()restituisce true e documentare questa soluzione alternativa correttamente ("perché è questo codice qui?").
Ulrich Eckhardt,

43

È lento. Dipende dalla piattaforma. È insicuro.

Primo: cosa fa. Chiamare "sistema" è letteralmente come digitare un comando nel prompt dei comandi di Windows. C'è una tonnellata di configurazione e smontaggio per la tua applicazione per effettuare tale chiamata - e il sovraccarico è semplicemente ridicolo.

Cosa accadrebbe se un programma chiamato "pause" fosse inserito nel PERCORSO dell'utente? Il solo sistema di chiamata ("pausa") garantisce solo l'esecuzione di un programma chiamato "pausa" (spero che tu non abbia l'eseguibile chiamato "pausa"!)

Scrivi semplicemente la tua funzione "Pause ()" che utilizza _getch. OK, certo, _getch dipende anche dalla piattaforma (nota: è definito in "conio.h") - ma è molto più bello che system()se stai sviluppando su Windows e ha lo stesso effetto (anche se è tua responsabilità fornire il testo con cout o giù di lì).

Fondamentalmente: perché introdurre così tanti potenziali problemi quando puoi semplicemente aggiungere due righe di codice e una include e ottenere un meccanismo molto più flessibile?


61
Per qualcuno che si lamenta della dipendenza dalla piattaforma, sembra sicuramente strano suggerire _getch, specialmente quando lo standard C ++ fornisce getchar.
paxdiablo,

33
provo un po 'di ironia nel calcolare le spese generali per l'interazione con un essere umano)
ShPavel,

1
@Spagpants: forse non capisci la differenza tra ricevere input da un essere umano e generare immagini e suoni da un essere umano.
yzt

1
@ Cheersandhth.-Alf - Hm? Quando ho scritto questo, 8 anni fa, avevo appena finito di eseguire il debug di un problema causato da "system (" pause ") perché il nome eseguibile del progetto era chiamato" pause "e sarebbe andato in un ciclo infinito. Il mio punto è ancora valido, non sono sicuro del motivo per cui stai dicendo che non ero corretto.

2
@paxdiablo getchar richiede un input e quindi premere invio. _getch richiede solo un tasto, indipendentemente da quale chiave sia. Per emulare _getch su Linux sono necessarie 5-6 righe di codice per modificare la modalità console, quindi ripristinarla ai valori predefiniti. Non è lo stesso, fa cose diverse. getchar non è un sostituto di _getch.
Barnack,

29
  • lento: deve saltare attraverso un sacco di codice Windows inutile e un programma separato per una semplice operazione
  • non portatile: dipende dal programma di pausa
  • stile non buono: effettuare una chiamata di sistema dovrebbe essere fatto solo quando veramente necessario
  • più digitando: System ("pause") è più lungo di getchar ()

un semplice getchar () dovrebbe andare bene.


26

L'utilizzo system("pause");è Ungood Practice ™ perché

  • È completamente inutile .
    Per mantenere la finestra della console del programma aperta alla fine quando la si esegue da Visual Studio, utilizzare Ctrl+ F5per eseguirla senza debug, oppure posizionare un punto di interruzione all'ultima parentesi graffa destra }di main. Quindi, nessun problema in Visual Studio. E ovviamente nessun problema quando lo esegui dalla riga di comando.

  • È problematico e fastidioso
    quando si esegue il programma dalla riga di comando. Per l'esecuzione interattiva è necessario premere un tasto alla fine senza alcuno scopo. E per l'uso nell'automazione di alcune attività pausemolto indesiderate!

  • Non è portatile.
    Unix-land non ha un pausecomando standard .

Il pausecomando è un cmd.execomando interno e non può essere ignorato, come erroneamente rivendicato in almeno un'altra risposta. Cioè non è un rischio per la sicurezza e l'affermazione che i programmi AV lo diagnosticano in quanto tale è dubbia come l'affermazione di ignorare il comando (dopotutto, un programma C ++ che invoca systemè in grado di fare tutto ciò che l'interprete di comandi può fare, e Di Più). Inoltre, mentre questo modo di mettere in pausa è estremamente inefficiente per i soliti standard di programmazione C ++, ciò non ha importanza alla fine del programma per principianti.

Quindi, le affermazioni nell'orda di risposte prima non sono corrette e il motivo principale che non dovresti usare system("pause") o qualsiasi altro comando wait alla fine del tuo mainè il primo punto sopra: è completamente inutile, non serve assolutamente a nessuno , è solo molto sciocco.


1
A volte è necessaria una Ungood Practice ™ per test rapidi .... quello che chiamiamo "veloce e sporco"
Michael Haephrati,

22

In breve, deve mettere in pausa l'esecuzione dei programmi ed effettuare una chiamata di sistema e allocare risorse non necessarie quando si potrebbe usare qualcosa di semplice come cin.get (). Le persone usano System ("PAUSE") perché vogliono che il programma attenda fino a quando non premono invio per vedere il loro output. Se vuoi che un programma attenda l'input, ci sono funzioni integrate per ciò che sono anche multipiattaforma e meno impegnative.

Ulteriori spiegazioni in questo articolo.


Caspita, di nuovo! vivi qui? lol Comunque, grazie, leggerò. Nel frattempo, quali sono i tuoi pensieri in merito?
Falso il

Avevo questa stessa domanda quando ho iniziato a scrivere C alcuni anni fa, e mi è stato indicato lo stesso articolo. Uso getchar () personalmente.
John T

Ho wow ... non ho fatto C ++ per un po ', ma sì .. ci sono modi decisamente migliori per ottenere gli stessi risultati
Newtopian,

16

Puoi usare std::cin.get()da 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;
}

Inoltre, system('pause')è lento, e include un file che probabilmente non avete bisogno: stdlib.h. Dipende dalla piattaforma e in realtà richiama un sistema operativo 'virtuale'.


3
Mi è stato insegnato a utilizzare System("pause")in un corso di programmazione del primo anno, ma volevo essere in grado di eseguire i miei programmi sul mio Mac, quindi ho dovuto imparare cin.get().
daviewales,

10

Perché non è portatile.

pause

è un programma solo windows / dos, quindi questo codice non funzionerà su linux. Inoltre, systemnon è generalmente considerato come un ottimo modo per chiamare un altro programma - di solito è meglio usare CreateProcesso forko qualcosa di simile.


4

Come elencato nelle altre risposte, ci sono molte ragioni che puoi trovare per evitarlo. Tutto si riduce a un motivo che fa discutere il resto. La System()funzione è intrinsecamente insicura / non attendibile e non dovrebbe essere introdotta in un programma se non necessario.

Per un incarico da studente, questa condizione non era mai soddisfatta, e per questo motivo avrei fallito un incarico senza nemmeno eseguire il programma se fosse presente una chiamata a questo metodo. (Ciò è stato chiarito dall'inizio.)


4

Per me non ha senso in generale aspettare prima di uscire senza motivo. Un programma che ha svolto il suo lavoro dovrebbe semplicemente finire e restituire le sue risorse al suo creatore.

Uno non aspetta silenziosamente in un angolo buio dopo una giornata di lavoro, aspettando che qualcuno si stacchi una spalla.


7
Questa è una risposta sciocca. Parte di un programma "facendo il suo lavoro" sta mostrando all'utente i risultati del suo lavoro. Pertanto, non deve terminare fino a quando l'utente non lo notifica di aver terminato. Un programma che scompare dallo schermo dell'utente un nanosecondo dopo che mostra i suoi risultati, è inutile.
JBentley,

1
@JBentley: ho parlato della situazione dopo aver visualizzato i risultati, se presenti. Per visualizzare i risultati, esistono schemi appropriati, come segnali, interruzioni, timer, scorrimento nel terminale, file. system("pause")di per sé non mostra nulla. Un programma di interfaccia a riga di comando che non viene richiamato dalla riga di comando e si chiude troppo presto viene invocato in modo errato e con le opzioni sbagliate e l'utilizzo system("pause")per eludere un programma invocato in modo errato non è davvero la cosa giusta da fare.
Sebastian Mach,

1
Voglio dire, solo immaginare cat, less, vi, OpenOffice, Mathematica, GNU Octave, che cosa se ne userei system("pause")? Sarebbe fastidioso.
Sebastian Mach,

2
Sì, sarebbe fastidioso, ma ora stai specificamente parlando dei problemi di system("pause"), mentre la tua risposta parla di "aspetta prima di uscire", che è un concetto molto più generalizzato. Molti degli esempi che hai dato infatti "aspettano prima di uscire", fino a quando l'utente informa il programma che vuole che esca. Sono d'accordo che system("pause")non è un buon modo per raggiungere questo obiettivo e che esistono soluzioni migliori, ma non è quello che dice la tua risposta.
JBentley,

1
@JBentley Oh, assolutamente: se un ritardo / attesa / prompt fa parte della semantica del programma, pausevia!
Razze di leggerezza in orbita

3
system("pause");  

è sbagliato perché fa parte dell'API di Windows e quindi non funzionerà in altri sistemi operativi.

Dovresti provare a usare solo oggetti dalla libreria standard C ++. Una soluzione migliore sarà scrivere:

cin.get();
return 0;

Ma causerà anche problemi se hai altri messaggi cinnel tuo codice. Perché dopo ognuno cin, toccherai un Entero \nche è uno spazio bianco. cinignora questo personaggio e lo lascia nella zona buffer, ma cin.get()ottiene questo carattere rimasto. Quindi il controllo del programma raggiunge la linea return 0e la console si chiude prima di farti vedere i risultati.
Per risolvere questo, scriviamo il codice come segue:

cin.ignore();  
cin.get();  
return 0;

È leggermente fuorviante. system()è standard e non specifico per MS Windows. Tuttavia, il pausecomando shell è un'eredità DOS e in genere si trova solo lì.
Ulrich Eckhardt,

1

Ecco un motivo per cui non dovresti usarlo: farà incazzare la maggior parte dei programmi antivirus in esecuzione su Windows se stai passando il programma su un altro computer perché è una minaccia alla sicurezza. Anche se il tuo programma è composto da una semplice cout << "hello world\n"; system("pause"); risorsa pesante e il programma accede al comando cmd, che gli antivirus considerano una minaccia.


-1

i pro utilizzano il sistema ("PAUSE"); mentre la creazione di piccole parti del programma è per il debug da soli. se lo usi per ottenere risultati delle variabili prima e dopo ogni processo che stai utilizzando per assicurarti che funzionino correttamente.

Dopo averlo testato e spostato a pieno regime con il resto della soluzione, è necessario rimuovere queste linee. è davvero utile quando si verifica un algoritmo definito dall'utente e si assicura che si stanno facendo le cose nell'ordine corretto per i risultati desiderati.

Non vuoi assolutamente usarlo in un'applicazione dopo averlo testato e assicurato che funzioni correttamente. Tuttavia ti consente di tenere traccia di tutto ciò che sta accadendo mentre accade. Non utilizzarlo per le app per l'utente finale.


-3

È tutta una questione di stile. È utile per il debug ma non dovrebbe essere usato nella versione finale del programma. Non importa davvero il problema della memoria perché sono sicuro che quei ragazzi che hanno inventato il sistema ("pausa") stavano anticipando che sarebbe stato usato spesso. In un'altra prospettiva, i computer vengono limitati nella loro memoria per tutto ciò che utilizziamo sul computer in ogni caso e non rappresenta una minaccia diretta come l'allocazione dinamica della memoria, quindi lo consiglierei per il debug del codice, ma nient'altro.


6
Non importa davvero il problema della memoria perché sono sicuro che quei ragazzi che hanno inventato il sistema ("pausa") stavano anticipando che sarebbe stato usato spesso non ha alcun senso. Nessuno lo ha "inventato", è pausestato progettato per essere utilizzato nei programmi batch DOS, non è mai stato concepito per essere utilizzato in questo modo. Inoltre c'erano alternative migliori prima che qualcuno fosse mai abbastanza pazzo da scrivere la frase system("pause");.
che il
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.