System ("Pause"); - Warum ist es falsch?

131

Hier ist eine Frage, die ich nicht ganz verstehe:

Der Befehl system("pause");wird neuen Programmierern beigebracht, um ein Programm anzuhalten und auf die Fortsetzung einer Tastatureingabe zu warten. Es scheint jedoch von vielen erfahrenen Programmierern als etwas missbilligt zu werden, das nicht in unterschiedlichem Maße getan werden sollte.

Einige Leute sagen, es ist in Ordnung zu verwenden. Einige sagen, es darf nur verwendet werden, wenn Sie in Ihrem Zimmer eingesperrt sind und niemand zuschaut. Einige sagen, dass sie persönlich zu Ihnen nach Hause kommen und Sie töten werden, wenn Sie es benutzen.

Ich selbst bin ein neuer Programmierer ohne formale Programmierausbildung. Ich benutze es, weil mir beigebracht wurde, es zu benutzen. Was ich nicht verstehe ist, dass, wenn es nicht verwendet werden soll, warum wurde mir dann beigebracht, es zu verwenden? Oder ist es auf der anderen Seite wirklich nicht so schlimm?

Was denkst du über dieses Thema?

Gefälscht
quelle
Verwandte: stackoverflow.com/questions/900666/…
Gordon Gustafson
5
Anscheinend mögen die Leute ihre Anrufe, um wirklich effizient zu sein. Mit anderen Worten: "Beeil dich und hör auf!"
Lee Louviere
63
Sie wurden gelehrt , weil in der Regel Lehrer schlechte Programmierer sind
Weichen
Bitte lesen Sie diesen Rat, um gute Fragen zu stellen: [ Fragen stellen ], [Die perfekte Frage schreiben ].
Adi Inbar
9
@wich völlig Unsinn.
Michael Chourdakis

Antworten:

85

Es ist verpönt, weil es sich um einen plattformspezifischen Hack handelt, der nichts mit dem Erlernen der Programmierung zu tun hat, sondern um eine Funktion der IDE / des Betriebssystems zu umgehen. Das von Visual Studio aus gestartete Konsolenfenster wird geschlossen, wenn das Programm ausgeführt wurde Der neue Benutzer kann die Ausgabe seines neuen Programms nicht sehen.

Bodging in System ("Pause") führt das Windows-Befehlszeilenprogramm "Pause" aus und wartet, bis es beendet wird, bevor die Ausführung des Programms fortgesetzt wird. Das Konsolenfenster bleibt geöffnet, damit Sie die Ausgabe lesen können.

Eine bessere Idee wäre, einen Haltepunkt am Ende zu setzen und ihn zu debuggen, aber das hat wieder Probleme.

Ravuya
quelle
6
Visual Studio kann das Programm in zwei Modi ausführen: mit oder ohne Debugging. Im Debugging-Modus wird es am ersten Haltepunkt gestoppt. Wenn Sie keine definiert haben, wird das Programm ausgeführt und die Konsole geschlossen. Wenn Sie also möchten, dass das Konsolenprogramm gestoppt wird, legen Sie einfach einen Haltepunkt fest oder führen Sie ihn, noch besser, ohne Debugging aus! Dadurch wird das Programm ausgeführt und die Konsole gestoppt.
Ivan Mesic
Dies ist nicht nur eine Funktion von Visual Studio. Wenn Sie ein Konsolenprogramm unter Windows ausführen (dh keine Eingabeaufforderung laden und von dort aus ausführen), wird es auch geschlossen, wenn die Ausführung abgeschlossen ist.
JBentley
2
−1 Betreff: „Das von Visual Studio aus gestartete Konsolenfenster wird geschlossen, wenn das Programm ausgeführt wurde.“ Nein, nur, wenn das Programm im Debugger ausgeführt wird. Re "führt das Windows-Befehlszeilenprogramm" Pause "aus", nein, es gibt kein solches ( pauseist ein interner Befehl in cmd.exe). Die Liste der besseren Ideen fehlt ebenfalls stark.
Prost und hth. - Alf
Ich denke, diese Antwort ist die einzige, die den Aspekt berührt, dass dies eine Problemumgehung ist. Es umgeht das Verhalten einer bestimmten Ausführungsumgebung, die ein Terminalfenster schließt, bevor Sie die Programmausgabe lesen können. Was Sie tun sollten, ist diese Umgebung zu reparieren. Wenn dies nicht möglich ist, verwenden Sie diese Problemumgehung, möglicherweise nur, wenn IsDebuggerPresent()true zurückgegeben wird, und dokumentieren Sie diese Problemumgehung ordnungsgemäß ("Warum ist dieser Code hier?").
Ulrich Eckhardt
43

Es ist langsam. Es ist plattformabhängig. Es ist unsicher.

Erstens: Was es tut. Das Aufrufen von "system" ist buchstäblich wie das Eingeben eines Befehls in die Windows-Eingabeaufforderung. Es gibt eine Menge Setup und Teardown für Ihre Anwendung, um einen solchen Anruf zu tätigen - und der Overhead ist einfach lächerlich.

Was ist, wenn ein Programm namens "pause" in den PATH des Benutzers eingefügt wurde? Nur das Aufrufen von system ("pause") garantiert nur, dass ein Programm namens "pause" ausgeführt wird (ich hoffe, Sie haben Ihre ausführbare Datei mit dem Namen "pause" nicht!)

Schreiben Sie einfach Ihre eigene "Pause ()" - Funktion, die _getch verwendet. OK, sicher, _getch ist auch plattformabhängig (Hinweis: Es ist in "conio.h" definiert) - aber es ist viel schöner als system()wenn Sie unter Windows entwickeln und es hat den gleichen Effekt (obwohl es in Ihrer Verantwortung liegt, den Text bereitzustellen mit cout oder so).

Grundsätzlich gilt: Warum sollten so viele potenzielle Probleme auftreten, wenn Sie einfach zwei Codezeilen und eine einschließen und einen viel flexibleren Mechanismus erhalten können?

Jonathan Leffler
quelle
61
Für jemanden, der sich über Plattformabhängigkeit beschwert, scheint es sicher seltsam, dies vorzuschlagen _getch, insbesondere wenn Standard-C ++ bietet getchar.
Paxdiablo
33
Ich fühle etwas Ironie bei der Berechnung des Overheads für die Interaktion mit einem Menschen)
ShPavel
1
@Spagpants: Vielleicht verstehen Sie den Unterschied zwischen dem Erhalten von Eingaben von einem Menschen und dem Erzeugen von Bildern und Tönen bei einem Menschen nicht.
Yzt
1
@ Cheersandhth.-Alf - Hm? Als ich dies vor 8 Jahren schrieb, hatte ich gerade das Debuggen eines Problems beendet, das durch 'system ("pause")' verursacht wurde, da der ausführbare Name des Projekts "pause" hieß und in eine Endlosschleife überging. Mein Punkt bleibt bestehen, ich bin mir nicht sicher, warum Sie sagen, dass ich falsch lag.
2
@paxdiablo getchar benötigt eine Eingabe und drückt dann die Eingabetaste. _getch benötigt nur einen Tastendruck, egal um welche Taste es sich handelt. Um _getch unter Linux zu emulieren, benötigen Sie 5-6 Codezeilen, um den Konsolenmodus zu ändern und ihn dann wieder auf den Standardwert zurückzusetzen. Es ist nicht dasselbe, es macht verschiedene Dinge. getchar ist kein Ersatz für _getch.
Barnack
29
  • langsam: Es muss für eine einfache Operation durch viele unnötige Windows-Codes und ein separates Programm springen
  • nicht portabel: abhängig vom Pausenprogramm
  • Kein guter Stil: Ein Systemaufruf sollte nur durchgeführt werden, wenn dies wirklich notwendig ist
  • mehr tippen: System ("Pause") ist länger als getchar ()

Ein einfaches getchar () sollte gut funktionieren.

Gavin H.
quelle
26

Verwenden system("pause");ist Ungood Practice ™, weil

  • Es ist völlig unnötig .
    Um das Konsolenfenster des Programms am Ende geöffnet zu lassen, wenn Sie es in Visual Studio ausführen, verwenden Sie Ctrl+ F5, um es ohne Debugging auszuführen, oder setzen Sie einen Haltepunkt an die letzte rechte Klammer }von main. Also kein Problem in Visual Studio. Und natürlich überhaupt kein Problem, wenn Sie es über die Befehlszeile ausführen.

  • Es ist problematisch und ärgerlich,
    wenn Sie das Programm über die Befehlszeile ausführen. Für die interaktive Ausführung müssen Sie am Ende eine Taste ohne jeden Zweck drücken. Und zur Verwendung bei der Automatisierung einer Aufgabe, pausedie sehr unerwünscht ist!

  • Es ist nicht tragbar.
    Unix-Land hat keinen Standardbefehl pause.

Der pauseBefehl ist ein interner cmd.exeBefehl und kann nicht überschrieben werden, wie in mindestens einer anderen Antwort fälschlicherweise behauptet wird. Das heißt, es ist kein Sicherheitsrisiko, und die Behauptung, dass AV-Programme es als solches diagnostizieren, ist ebenso zweifelhaft wie die Behauptung, den Befehl zu überschreiben (schließlich ein C ++ - Programm, das aufgerufen wirdsystem in der Lage, alles zu tun, was der Befehlsinterpreter tun kann, und Mehr). Auch wenn diese Art der Pause nach den üblichen Standards der C ++ - Programmierung äußerst ineffizient ist, spielt dies am Ende des Programms eines Anfängers keine Rolle.

Die Behauptungen in der Horde der Antworten davor sind also nicht korrekt, und der Hauptgrund, warum Sie am Ende Ihres system("pause") Befehls keinen anderen Wartebefehl verwenden sollten main, ist der erste Punkt oben: Es ist völlig unnötig, es hat absolut keinen Zweck Es ist einfach sehr dumm.

Prost und hth. - Alf
quelle
1
Manchmal wird eine Ungood Practice ™ für schnelle Tests benötigt ... was wir "schnell und schmutzig" nennen
Michael Haephrati
22

Zusammenfassend muss die Programmausführung angehalten und ein Systemaufruf ausgeführt sowie unnötige Ressourcen zugewiesen werden, wenn Sie etwas so Einfaches wie cin.get () verwenden könnten. Benutzer verwenden System ("PAUSE"), weil sie möchten, dass das Programm wartet, bis sie die Eingabetaste drücken, um ihre Ausgabe zu sehen. Wenn Sie möchten, dass ein Programm auf Eingaben wartet, gibt es integrierte Funktionen für diejenigen, die auch plattformübergreifend und weniger anspruchsvoll sind.

Weitere Erläuterungen in diesem Artikel.

John T.
quelle
Wow, du schon wieder! lebst du hier? lol Wie auch immer, danke, ich werde etwas lesen. Was denken Sie in der Zwischenzeit über diese Angelegenheit?
Gefälschte
Ich hatte dieselbe Frage, als ich vor einigen Jahren mit C anfing, und ich wurde auf denselben Artikel verwiesen. Ich benutze getchar () persönlich.
John T
Ho wow ... Ich habe C ++ eine Weile nicht gemacht, aber ja ... es gibt definitiv bessere Möglichkeiten, um die gleichen Ergebnisse zu erzielen
Newtopian
16

Sie können verwenden std::cin.get()von 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;
}

Außerdem system('pause')ist es langsam und enthält eine Datei, die Sie wahrscheinlich nicht benötigen : stdlib.h. Es ist plattformabhängig und ruft tatsächlich ein "virtuelles" Betriebssystem auf.

Gavriel Feria
quelle
3
System("pause")In einem Programmierkurs im ersten Jahr wurde mir die Verwendung beigebracht , aber ich wollte meine Programme auf meinem Mac ausführen können, also musste ich etwas darüber lernen cin.get().
Daviewales
10

Weil es nicht tragbar ist.

pause

ist ein reines Windows / Dos-Programm, daher läuft Ihr Code nicht unter Linux. Darüber hinaus systemwird es im Allgemeinen nicht als eine sehr gute Möglichkeit angesehen, ein anderes Programm aufzurufen - es ist normalerweise besser, es zu verwenden CreateProcessoder forkähnliches.

a_m0d
quelle
4

Wie in den anderen Antworten aufgeführt, gibt es viele Gründe, dies zu vermeiden. Es läuft alles auf einen Grund hinaus, der den Rest zur Diskussion stellt. Die System()Funktion ist von Natur aus unsicher / nicht vertrauenswürdig und sollte nur dann in ein Programm eingeführt werden, wenn dies erforderlich ist.

Bei einer Schüleraufgabe wurde diese Bedingung nie erfüllt, und aus diesem Grund würde ich eine Aufgabe nicht bestehen, ohne das Programm auszuführen, wenn ein Aufruf dieser Methode vorhanden wäre. (Dies wurde von Anfang an klargestellt.)

Sam Harwell
quelle
4

Für mich macht es im Allgemeinen keinen Sinn, vor dem Verlassen ohne Grund zu warten. Ein Programm, das seine Arbeit erledigt hat, sollte einfach enden und seine Ressourcen an seinen Ersteller zurückgeben.

Man wartet auch nicht still nach einem Arbeitstag in einer dunklen Ecke und wartet darauf, dass jemand seine Schulter kippt.

Sebastian Mach
quelle
7
Dies ist eine dumme Antwort. Ein Teil eines Programms, das "seine Arbeit erledigt", besteht darin, dem Benutzer die Ergebnisse seiner Arbeit anzuzeigen. Es sollte daher nicht enden, bis der Benutzer ihm mitteilt, dass er damit fertig ist. Ein Programm, das eine Nanosekunde nach der Anzeige der Ergebnisse vom Bildschirm des Benutzers verschwindet, ist nutzlos.
JBentley
1
@JBentley: Ich habe über die Situation gesprochen, nachdem ich die Ergebnisse angezeigt habe , falls vorhanden. Für die Anzeige der Ergebnisse gibt es geeignete Muster wie Signale, Interrupts, Timer, Scrollback in Ihrem Terminal und Dateien. system("pause")an sich zeigt nichts an. Ein Befehlszeilenschnittstellenprogramm, das nicht über die Befehlszeile aufgerufen wird und zu früh geschlossen wird, wird falsch und mit den falschen Optionen aufgerufen, und die system("pause")Umgehung eines falsch aufgerufenen Programms ist wirklich nicht das Richtige.
Sebastian Mach
1
Ich meine, stellen Sie sich vor cat, less, vi, OpenOffice, Mathematica, GNU Octave, was ist, wenn sie würden verwenden system("pause")? Das wäre nervig.
Sebastian Mach
2
Ja, das wäre ärgerlich, aber jetzt sprechen Sie speziell über die Probleme von system("pause"), während Ihre Antwort von "Warten vor dem Beenden" spricht, was ein weitaus allgemeineres Konzept ist. Viele der von Ihnen angegebenen Beispiele warten tatsächlich "vor dem Beenden", bis der Benutzer das Programm darüber informiert, dass es beendet werden soll. Ich stimme zu, dass dies system("pause")kein guter Weg ist, um dies zu erreichen, und dass es bessere Lösungen gibt, aber das sagt Ihre Antwort nicht.
JBentley
1
@JBentley Oh, absolut: Wenn eine Verzögerung / Wartezeit / Eingabeaufforderung Teil der Semantik des Programms ist, pauseweg!
Leichtigkeitsrennen im Orbit
3
system("pause");  

ist falsch, weil es Teil der Windows-API ist und daher in anderen Betriebssystemen nicht funktioniert.

Sie sollten versuchen, nur Objekte aus der C ++ - Standardbibliothek zu verwenden. Eine bessere Lösung wird sein zu schreiben:

cin.get();
return 0;

Es wird aber auch Probleme verursachen, wenn Sie andere cins in Ihrem Code haben. Denn nach jedem cintippen Sie auf ein Enteroder \nein Leerzeichen. cinignoriert dieses Zeichen und belässt es in der Pufferzone cin.get(), erhält aber dieses verbleibende Zeichen. Die Steuerung des Programms erreicht also die Zeile return 0und die Konsole wird geschlossen, bevor Sie die Ergebnisse sehen können.
Um dies zu lösen, schreiben wir den Code wie folgt:

cin.ignore();  
cin.get();  
return 0;
Sepideh Abadpour
quelle
Das ist etwas irreführend. system()ist Standard und nicht spezifisch für MS Windows. Der pauseShell-Befehl ist jedoch ein DOS-Erbe und wird normalerweise nur dort gefunden.
Ulrich Eckhardt
1

Hier ist ein Grund, warum Sie es nicht verwenden sollten: Es wird die meisten unter Windows laufenden Antivirenprogramme verärgern, wenn Sie das Programm auf einen anderen Computer übertragen, da es eine Sicherheitsbedrohung darstellt. Selbst wenn Ihr Programm nur aus einer einfachen cout << "hello world\n"; system("pause"); Ressource besteht, ist es ressourcenintensiv und das Programm erhält Zugriff auf den Befehl cmd, den Antiviren als Bedrohung ansieht.

Andreas DM
quelle
-1

die Profis verwenden das System ("PAUSE"); Während Sie die kleinen Teile Ihres Programms erstellen, müssen Sie es selbst debuggen. Wenn Sie damit vor und nach jedem Prozess Ergebnisse von Variablen abrufen, stellen Sie sicher, dass diese ordnungsgemäß funktionieren.

Nachdem Sie es getestet und mit dem Rest der Lösung auf Hochtouren gebracht haben, sollten Sie diese Leitungen entfernen. Es ist wirklich gut, wenn Sie einen benutzerdefinierten Algorithmus testen und sicherstellen, dass Sie die Dinge in der richtigen Reihenfolge ausführen, um die gewünschten Ergebnisse zu erzielen.

Sie möchten dies auf keinen Fall in einer Anwendung verwenden, nachdem Sie sie getestet und sichergestellt haben, dass sie ordnungsgemäß funktioniert. Es ermöglicht Ihnen jedoch, alles im Auge zu behalten, was gerade passiert. Verwenden Sie es überhaupt nicht für Endbenutzer-Apps.

Niemand Bestimmtes
quelle
-3

Es ist alles eine Frage des Stils. Es ist nützlich zum Debuggen, sollte aber ansonsten nicht in der endgültigen Version des Programms verwendet werden. In Bezug auf das Speicherproblem spielt das keine Rolle, da ich sicher bin, dass die Leute, die das System erfunden haben ("Pause"), damit gerechnet haben, dass es häufig verwendet wird. In einer anderen Perspektive werden Computer für alles andere, was wir auf dem Computer verwenden, in ihrem Speicher gedrosselt, und es stellt keine direkte Bedrohung wie die dynamische Speicherzuweisung dar. Daher würde ich es zum Debuggen von Code empfehlen, aber sonst nichts.

Jason A.
quelle
6
Es spielt wirklich keine Rolle in Bezug auf das Speicherproblem, da ich sicher bin, dass die Leute, die das System erfunden haben ("Pause"), damit gerechnet haben, dass es oft verwendet wird, was überhaupt keinen Sinn ergibt. Niemand "erfand" dies, pausewurde für die Verwendung in DOS-Batch-Programmen entwickelt, es war nie beabsichtigt, auf eine solche Weise verwendet zu werden. Darüber hinaus gab es viel bessere Alternativen, bevor jemand jemals verrückt genug war, den Satz zu tippen system("pause");.
Weichen