Warum kein system("PAUSE"); vor und nachteile ?


  • Administrator

    Nexus schrieb:

    Fellhuhn schrieb:

    Warum nicht einfach das Programm aus einer Konsole heraus starten?

    Weil es mühsam ist, nicht einfach in der IDE einen einzigen Knopf zu drücken 😉

    <CTRL>+<F5> (zumindest unter MSVC)
    Dies startet allerdings nicht den Debugger, kann man dann aber im Nachhinein starten lassen. Dafür hat es am Ende automatisch ein "Bitte drücken sie eine beliebige Taste...".

    Grüssli



  • Nexus schrieb:

    Fellhuhn schrieb:

    Warum nicht einfach das Programm aus einer Konsole heraus starten?

    Weil es mühsam ist, nicht einfach in der IDE einen einzigen Knopf zu drücken 😉

    Selbst wenn sonst nichts greift, warum nicht einfach einen Breakpoint setzen? 😉



  • Fellhuhn schrieb:

    Selbst wenn sonst nichts greift, warum nicht einfach einen Breakpoint setzen? 😉

    Oder warum nicht einfach system("pause") verwenden, wenn man damit keine Probleme hat und auch in absehbarer Zukunft keine damit haben wird? Dann kann man Programme auch direkt als Anwendung aus dem Windows Explorer starten.



  • Nexus schrieb:

    Fellhuhn schrieb:

    Selbst wenn sonst nichts greift, warum nicht einfach einen Breakpoint setzen? 😉

    Oder warum nicht einfach system("pause") verwenden, wenn man damit keine Probleme hat und auch in absehbarer Zukunft keine damit haben wird? Dann kann man Programme auch direkt als Anwendung aus dem Windows Explorer starten.

    endlich ma jmd, der das auch so sieht... Klar kann man auch dies, das und jenes machen und dann trotzdem noch unendlich viele Nachteile haben - aber man kann auch einfach system ("pause"); nutzen und sich freuen, dass man echt nix machen muss und trotzdem alles genau so gut klappt... Btw seh ich auch keinen Nachteil bei so einer Fkt:
    - sie ist meines erachtens nacht os-unabhängig, weil diese fkt von jedem os geboten wird...
    - die Geschwindigkeit (was sonst immer das größte Prob ist - von wegen extra shell öffnen, ...) ist eh egal, weil danach eh erst ma auf ne eingabe gewartet werden muss...

    bb



  • Gut, dass ich nicht der einzige bin 🙂

    Naja, bei paar Dingen habe ich sowieso das Gefühl, viele Leute halten sie für böse, aber wirklich Argumente gegen einen bestimmten Anwendungsfall gibts nicht (soll natürlich nicht heissen, dass system keine Nachteile hätte)... 😉



  • Nexus schrieb:

    Naja, bei paar Dingen habe ich sowieso das Gefühl, viele Leute halten sie für böse, aber wirklich Argumente gegen einen bestimmten Anwendungsfall gibts nicht (soll natürlich nicht heissen, dass system keine Nachteile hätte)... 😉

    Ist wahrscheinlich ähnlich goto oder dass Funktionen nicht länger als X Zeilen lang sollen. Man sollte sowas nicht großzügig überall im Code einsetzen, aber um schnell mal was zu erreichen oder wenn's in einer konkreten, eingegrenzten Situation nun mal Vorteile hat (z.B. schnellster Wildcard-Match-Algorithmus den ich kenne arbeitet mit 'goto's), kann man's ja ruhig machen.



  • - Konsolenprogramme beenden sich. Wenn mal ein system("pause") vergessen wird schimpft der Kunde 😃
    - pause.exe gibt's nicht auf jedem System.
    - seltsamerweise ist noch niemand auf die Idee gekommen, eine Ausgabe per system("echo hallo") zu coden, aber die einfache Aufgabe, auf eine Eingabe zu warten, soll an das System delegiert werden.

    Vor allem den letzten Punkt finde ich unter dem Gesichtspunkt, dass man doch Programmieren lernen möchte, eher bedenklich. 🙂



  • Nexus schrieb:

    Trotzdem finde ich system("pause") gar nicht so übel. Bei std::cin.get() muss man womöglich noch den Puffer leeren, und manchmal sind zwei Eingaben erforderlich. Zudem funktioniert nur die Enter-Taste.

    Wäre da nicht "while(!_kbhit());" eine Alternative?



  • _matze schrieb:

    Wäre da nicht "while(!_kbhit());" eine Alternative?

    klar. Du kannst auch die Funktion Wurstbrot() aufrufen und hoffen dass es funktioniert - Tatsache ist, dass weder system("pause") noch _kbhit() Standardkonform sind und damit nur eingeschränkt oder garnicht portabel.

    Tatsache ist auch, dass das "Hilfe-meine-Konsole-geht-zu"-Problem kein C++-Problem ist, und auch nur zum Teil ein OS-Problem, sondern vielmehr ein Anwenderproblem. Wenn der Anwender Konsolenprogramme nicht aus der Konsole sondern vom Desktop aus startet muss er damit rechnen dass es Effekte gibt die beim Start aus der Konsole nicht vorkommen.
    Man könnte natürlich argumentieren dass das trotzdem möglich sein sollte, weil ja viele Anwender ihre Programme vom Desktop aus starten - es gibt aber auch einige Anwender die nur von der Konsole aus arbeiten, sollte denen dann nicht auch ermöglicht werden, ihre GUI-Anwendungen einfach aus der Konsole zu starten? Ich möchte von meinem DOS-Rechner aus (oder auf meinem Server der eh keine grafische Oberfläche hat) ein Programm starten das eine GUI hat - also hätte ich gern einen Einzeiler á la system("pause") der mir in einem Kommandozeilen-OS mal eben on the fly einen grafischen Desktop aufbaut damit ich die GUI meines Programms sehe. </ironie>

    mein Fazit ist, es gibt zwei Möglichkeiten:
    a) Ich schreibe ein standardkonformes portables Konsolenprogramm. Konsolenprogramme sollten von der Konsole aus gestartet werden und bracuhen daher keinen "halt-mir-die-konsole-offen"-Schnickschnack.
    b) Ich schreibe ein Konsolenprogramm das vom Dekstop meines grafischen OS aus gestartet werden kann und offen bleiben soll. Das ist dann eh nicht portabel (nicht jedes OS ist grafisch), also kann ich auch nichtportable Funktionen benutzen.



  • pumuckl schrieb:

    Tatsache ist, dass weder system("pause") noch _kbhit() Standardkonform sind und damit nur eingeschränkt oder garnicht portabel.

    Das ist mir, ehrlich gesagt, ziemlich egal. Portabilität interessiert mich nicht. Ich schreibe beruflich und privat ausschließlich Windows-Anwendungen. _kbhit ist (unter Win) eine gute Altertative zum cin.get, bei dem wie gesagt die Enter-Taste gedrückt werden muss.

    pumuckl schrieb:

    Man könnte natürlich argumentieren dass das trotzdem möglich sein sollte, weil ja viele Anwender ihre Programme vom Desktop aus starten - es gibt aber auch einige Anwender die nur von der Konsole aus arbeiten, sollte denen dann nicht auch ermöglicht werden, ihre GUI-Anwendungen einfach aus der Konsole zu starten?

    Wenn ich dein Zitat so für sich stehen lasse, dann würde ich mal sagen: problemlos möglich!

    pumuckl schrieb:

    Ich möchte von meinem DOS-Rechner aus (oder auf meinem Server der eh keine grafische Oberfläche hat) ein Programm starten das eine GUI hat

    Das natürlich nicht... 😉

    pumuckl schrieb:

    mein Fazit ist, es gibt zwei Möglichkeiten:
    a) Ich schreibe ein standardkonformes portables Konsolenprogramm. Konsolenprogramme sollten von der Konsole aus gestartet werden und bracuhen daher keinen "halt-mir-die-konsole-offen"-Schnickschnack.
    b) Ich schreibe ein Konsolenprogramm das vom Dekstop meines grafischen OS aus gestartet werden kann und offen bleiben soll. Das ist dann eh nicht portabel (nicht jedes OS ist grafisch), also kann ich auch nichtportable Funktionen benutzen.

    Ich wähle guten Gewissens b). Wer a) wählt, kann ja während der Entwicklungsphase trotzdem mit nicht standardkonformen Methoden dafür sorgen, dass seine Win-Konsole offen bleibt, und diese dann zum Schluss entfernen. Optimaler Komfort während der Entwicklung und als Ergebnis totale Portabilität! 🙂



  • _matze schrieb:

    Wer a) wählt, kann ja während der Entwicklungsphase trotzdem mit nicht standardkonformen Methoden dafür sorgen, dass seine Win-Konsole offen bleibt, und diese dann zum Schluss entfernen. Optimaler Komfort während der Entwicklung und als Ergebnis totale Portabilität! 🙂

    Wenn schon, dann sollte man das über Release/Debug und die entsprechenden Makros entfernen lassen. Selbst etwas zu Debugging-Zwecken einzubauen (mit dem Ziel, es später manuell wieder zu entfernen) verleitet dazu, es zu vergessen.

    Und den optimalen Komfort erreicht man auch durch eine vernünftige IDE, die das für einen macht - das ist sogar optimaler (:p), weil kein zusätzlicher Code nötig ist.



  • unskilled schrieb:

    - sie ist meines erachtens nacht os-unabhängig, weil diese fkt von jedem os geboten wird...

    Nein, das ist dann ein reines DOS/Windows Programm. Man sollte beim Programmieren als erstes lernen, daß man sich auf zugesicherte Eigenschaften der jeweiligen Umgebung verläßt, und darüber hinaus keinerlei implizite Erwartungen an die Umgebungen haben.

    Wenn man reines C++ programmiert, dann hat das system("PAUSE") rein gar nichts zu suchen.


  • Administrator

    Wann benutzt ihr eigentlich system("PAUSE") , bzw. ein std::cin.get() und co?
    Also ich persönlich verwende sowas nur in meiner Testanwendung und früher in Übungsbeispielen. Ansonsten muss bei mir normalerweise der Benutzer ein Kommando eingeben, sei es eine 0 oder ein "quit", damit überhaupt erst das Konsolenprogramm beendet wird.

    Daher:
    - In Übungsbeispielen ist es ein Anfänger. Anfängern sollte man erst gar nie etwas falsches beibringen, auch nicht, wenn es teilweise richtig ist. Sie sollten, wenn sie C++ lernen, reines korrektes C++ auch lernen.
    - In der Testanwendungen habe ich persönlich immer bereits ein wait() vorprogrammiert. Da ich eigentlich immer die gleiche Testanwendung verwende, kann ich immer dieses wait() benutzen. Ich habe das Ding auch in einem "Test.hpp" drin, wo ich allerhand anderer für mich kleine Tools zum testen habe.

    Ich selber benutze kein system("PAUSE") auch an Stellen, wo es keine Probleme machen würde, aus dem einfachen Grund, weil ich mich erst gar nicht an etwas gewöhnen will, was Fehler verursachen könnte. Und man gewöhnt sich an so Dinge schneller als einem lieb ist.

    "Ach nur hier, das ist eine kleine Anwendung!"
    "Das wird sicher auch gehen!"
    "Ich korrigiere es dann später noch um!"
    "Momentan macht es keine Probleme!"
    usw.

    Ich würde es mit dem Autofahren mit Sandalen vergleichen. Das kann gut gehen, das kann tausend Male gutgehen. Man gewöhnt sich dran, es hat ja noch nie ein Problem verursacht. Bis es dann mal soweit ist und die Situation kommt, wo du mit richtigen Schuhen kein Problem gehabt hättest. Nur weil du zu faul warst, schnell die Schuhe anzuziehen ... Nur weil du zu faul warst, ein zwei Zeilen mehr zu schreiben 😉
    Deshalb es erst gar nicht verwenden, es verhindert Probleme, auch wenn diese erst in 10 Jahren oder sonst wann auftauchen!

    Grüssli



  • Naja... Ich verwende es eigentlich auch nur in Testanwendungen, da ich sonst eigentlich gar nicht mit der Konsole arbeite. Und ich bin mir auch sehr bewusst, dass system("pause") nicht gerade optimal ist. Ich gewöhn mich weder so schnell daran, noch vergesse ich von heute auf morgen, dass es ja auch Nachteile hat. Von daher gesehen ist es für mich durchaus legitim.

    Und was die Anfänger betrifft: cin.get() (oder allgemein cin ) ist eigentlich die einzige, wirklich Standard-C++-Methode. Dass man sich bereits bei Hello-World-Programmen mit Pufferleeren und Ignorieren herumschlagen muss und trotzdem nicht einfach nur auf Enter drücken kann, fördert weder die Motivation am Programmieren noch den Lernprozess. Deshalb system("pause") - dem Programmierer sollten eben beide Seiten gezeigt werden und er soll merken, dass das keine langfristige Lösung ist. Aber wenn man länger programmiert, hört man sicher auch irgendwann von den Nachteilen.

    Es ist ja eigentlich genauso mit using namespace std; . Das schreibt auch jeder Anfänger, um die explizite Namensraum-Deklaration zu vermeiden. Aber wie viele sind sich tatsächlich bewusst, was die Anweisung macht? Man schreibt es halt einfach, auch aus Gewohnheit. Später erfährt man vielleicht teilweise, was es bewirkt, ist sich der Konsequenzen dennoch nicht bewusst. Dann ist es nur noch ein kleiner Schritt, bis man es auch in Header schreibt und die ersten Namenskonflikte bekommt.

    Oder char* wird immer noch zu häufig, gerade von Anfängern, für Zeichenketten benutzt. Natürlich ist sich keiner von denen der Probleme bewusst.

    Manche Dinge können meiner Ansicht nach eben nicht von Anfang richtig bzw. vollständig erklärt werden. Für den Anfang ist es auch besser, man überlässt gewisse Aufgaben bestimmten Sprachmitteln und Funktionen, die man später immer noch selbst in die Hand nehmen kann.



  • pharmacy;


  • Administrator

    Nexus schrieb:

    Ich gewöhn mich weder so schnell daran, noch vergesse ich von heute auf morgen, dass es ja auch Nachteile hat.

    Das habe ich schon oft gehört und am Ende hat sich derjenige trotzdem rasant daran gewöhnt. Ich verweise auf die bereits genannten Zitate 😃
    Wieso überhaupt diese Gefahr eingehen?

    Nexus schrieb:

    Und was die Anfänger betrifft: cin.get() (oder allgemein cin ) ist eigentlich die einzige, wirklich Standard-C++-Methode. Dass man sich bereits bei Hello-World-Programmen mit Pufferleeren und Ignorieren herumschlagen muss und trotzdem nicht einfach nur auf Enter drücken kann, fördert weder die Motivation am Programmieren noch den Lernprozess. Deshalb system("pause") - dem Programmierer sollten eben beide Seiten gezeigt werden und er soll merken, dass das keine langfristige Lösung ist. Aber wenn man länger programmiert, hört man sicher auch irgendwann von den Nachteilen.

    Du solltest dann aber das gleiche Argument für system("PAUSE") anwenden. In einem einfachen "Hello World"-Programm dem Anfänger beibringen, was system("PAUSE") macht und welche Nachteile es hat. Auch nicht gerade motivierend, nicht?
    Zudem:
    1. C++ war, ist und wird wohl auch nie eine Anfänger freundliche Sprache werden. Daher am besten erst gar nicht als solche verkaufen!
    2. Du musst dem Anfänger nicht unbedingt von Anfang an erklären, was std::cin.ignore , std::cin.clear und std::cin.get ist oder tut, genau so wenig, wie du es bei system("PAUSE") vor hättest. Das kann auf später verschoben werden und wenn es dann genauer erklärt wird, kann als zweites noch system("PAUSE") erwähnt werden. Also zuerst das Fehlersichere beibringen und danach, wenn sich derjeniger an diese Methode gewöhnt hat, das andere auch noch aufzeigen.
    Das ist grundsätzlich ähnlich wie mit dem goto . Zuerst wird einem if-else if-else , for , (do-)while beigebracht, damit man immer zuerst an diese denkt. Und später wird noch goto erwähnt, damit man dieses wirklich nur zum optimieren einsetzt.
    3. Der Anfänger wird extrem motiviert, wenn er C++ lernen will und seine Übungen nicht funktionieren, weil der Autor so dumm war und mit system("PAUSE") nur an Windows-Leser gedacht hat. Gibt bekanntlich auch Leute, welche C++ auf Linux, Mac oder irgendwelche exotischen Betriebsystemen lernen.

    Nexus schrieb:

    Es ist ja eigentlich genauso mit using namespace std; . Das schreibt auch jeder Anfänger, um die explizite Namensraum-Deklaration zu vermeiden.

    Und ich finde das extrem schlecht! Auch von Tutorials und Bücher, welche sowas vermitteln. Solche Dinge sollten bewusst nach hinten verlegt werden und erst später und dann präzise behandelt werden.

    Nexus schrieb:

    Oder char* wird immer noch zu häufig, gerade von Anfängern, für Zeichenketten benutzt. Natürlich ist sich keiner von denen der Probleme bewusst.

    Aber sie sollten es verwenden, oder wie? std::string ist für den Anfänger deutlich angenehmer zu benutzen. Ich verstehe bei diesem Satz nicht so recht, auf was du hinaus willst? Weil viele Anfänger den Fehler machen, ihr Leben schwieriger zu gestalten, indem sie char* benutzen, sollten sie am besten ihr Leben noch schwerer machen, in dem sie system("PAUSE") verwenden ... oder wie jetzt? 🙂

    Nexus schrieb:

    Für den Anfang ist es auch besser, man überlässt gewisse Aufgaben bestimmten Sprachmitteln und Funktionen, die man später immer noch selbst in die Hand nehmen kann.

    Genau, gewisse Dinge müssen nicht von Anfang an erklärt werden und können mit einem Kapitelverweis auf Später verschoben werden.

    Grüssli



  • Mal sehen, ob es wieder eine Riesendiskussion gibt 😉

    Das Problem mit cin.get() ist leider einfach, dass es nicht einfach so funktioniert, wenn cin bereits vorher verwendet wurde. Und ich weiss ja nicht, wie gut man sich alle Funktionen zum Leeren und Resetten von cin merken kann...

    Aber stimmt, du hast schon Recht, system("pause") in Büchern zu bringen wäre unsinnig (nur schon wegen der Portabilität). Ursprünglich wollte ich ja nur darauf hinaus, dass es grundsätzlich nicht schlimm wäre, es (unter Windows) zu benutzen, wenn man die Gefahren kennt. Was natürlich für den Anfänger nicht gilt. Hm... Und ja, anfängerfreundlich ist C++ wirklich nicht 🙂

    Und was char* betrifft: Eigentlich wollte ich genau sagen, dass Anfänger es besser nicht (oder nicht ausführlich) verwenden und zu std::string greifen sollten... Tut mir leid, wenn ich mich unklar ausgedrückt habe 😉



  • pharmacy;


  • Administrator

    Nexus schrieb:

    Mal sehen, ob es wieder eine Riesendiskussion gibt 😉

    Ich hoffe nicht, sonst werfen die mich noch aus dem Forum 🙂

    Nexus schrieb:

    Das Problem mit cin.get() ist leider einfach, dass es nicht einfach so funktioniert, wenn cin bereits vorher verwendet wurde. Und ich weiss ja nicht, wie gut man sich alle Funktionen zum Leeren und Resetten von cin merken kann...

    Nexus schrieb:

    Aber ob cin.get() so viel besser ist? :p

    Also ich persönlich tendiere sowieso dazu, dass man überhaupt gar kein std::cin.get oder system("PAUSE") am Ende eines Konsolenprogrammes anfügt. Daher auch bei einem Tutorial nicht. Man könnte vielleicht die Anmerkung hinsetzen, dass das Programm sofort beendet wird, wenn man das nicht möchte, kann man die folgende Funktion benutzen:

    void wait()
    {
      std::cin.ignore(std::cin.rdbuf()->in_avail());
      std::cin.clear();
      std::cin.get();
    }
    

    -> Aus dem Kopf aufgeschrieben (ich hoffe mal es stimmt 🙂 ).

    Falls der Anfänger nun diese Funktion wirklich einsetzen möchte, kann er immer wieder diese paar Zeilen abschreiben. Irgendwann kann er es auswendig 🙂
    Und neben dieser Funktion dann natürlich ein Kapitelverweis 😉

    Nexus schrieb:

    Ursprünglich wollte ich ja nur darauf hinaus, dass es grundsätzlich nicht schlimm wäre, es (unter Windows) zu benutzen, wenn man die Gefahren kennt. Was natürlich für den Anfänger nicht gilt.

    Ich halte dies wie mit dem Optimieren. Zuerst etwas schreiben, was GANZ SICHER geht. Danach optimieren! Lieber erst später die Sache durch ein system("PAUSE") ersetzen. Am besten also die Funktion wait() oder ähnliches verwenden. Danach kannst du nur noch deren Implementation abändern. Aber ich wäre ja mal gespannt, ob das wirklich überhaupt jemand ändern würde, denn Vorteile hat man keine.

    Grüssli

    PS: Könnte jemand die Moderatoren oder Administratoren benachrichtigen? Hier spamt ein Bot das ganze Forum zu!



  • Hehe, 7 Edits für eine Editierung... Ich meld mich glaub wieder mal in der Forentechnik wegen des langsamen Boards...

    Hm... Vielleicht bin ich hier ein bisschen ein Heuchler, da ich selber am Anfang auch genau diese Wait-Funktion benutzte 😉

    Vorteile hat man bei system("pause") aber schon, denn abgesehen vom kürzeren Code kann man eine beliebige Taste drücken, es wird einem gleich angezeigt, dass man eine Taste drücken muss, und man braucht nur einmal zu drücken. Aber für die Nachteile lohnt es sich halt nicht unbedingt...

    Naja, es ist möglicherweise nicht sehr geeignet für Anfänger (wobei man hier noch stundenlang diskutieren könnte, ich lass es jetzt mal :))... Aber so kurz in einem Testprojekt finde ich es schon unheimlich praktisch und werde es auch weiterhin benutzen 😉


Anmelden zum Antworten