Warum kein system("cls") verwenden?



  • Meine Bemerkungen beziehen sich zu system() unter MS-Dos oder Windows.
    Unter Linux ist das eventuell anders.

    Wie Martin schon erwähnte, Du erzeugst einen neuen Prozess.
    Das kann Ressourcenprobleme bedeuten.
    Du musst sicherstellen, dass der Parameter von system() sinnvoll und vorhanden ist auf den Systemen, auf denen Dein Programm läuft. Persönlich betrachte ich den Parameter als freundliche, spekulative Annahme.
    Dein Programm wartet im Ablauf darauf, dass ein Return zurück kommt bzw. der Prozess endet.
    Das kann je nach Parameter von system eine Neu-Inszenierung von "Warten auf Godot" werden.
    Die "bösen" Beispiele, die ich bis jetzt gesehen haben, weigerten sich auch konsequent den Return auszuwerten.
    Der Return kommt übrigens von cmd.exe/coomand.com und muss nicht dem Return eines als Parameter auf gerufenen Programmes entsprechen. Du vergibst hiermit die Kontrolle über Deinen Programmfluss und kannst Fehler nicht abfangen oder verarbeiten. Willkommen auf der Dunklen Seite 😃

    Weiterhin hat der neue Prozess eine andere comspec- und path-Variable als der Aufrufende, nämlich die des aufgerufenen ( wenn vorhandenen ) cmd.exe.

    Auch muss man aktuelle Streams flushen oder schliessen bevor man system nutzt.

    Das Nutzen betriebssystemspezifischer Hardwarsteuerung(im Thread beschrieben) in eigenen Modulen/Bibliotheken ist sauberer und der Programmierer hält die Kontrolle über das Programm.



  • Ok, viele dank für die schnellen Antworten 😃

    Jetzt kapier ich das auch endlich mal



  • Shiba schrieb:

    Meine Bemerkungen beziehen sich zu system() unter MS-Dos oder Windows.
    Unter Linux ist das eventuell anders.

    Ganz sicher sogar, denn sonst würden wir über system("clear"); reden.

    Shiba schrieb:

    Wie Martin schon erwähnte, Du erzeugst einen neuen Prozess.
    Das kann Ressourcenprobleme bedeuten.

    Also reden wir über DOS. Da inkludiert man einfach die <conio.h> und hat clrscr();

    Shiba schrieb:

    Du musst sicherstellen, dass der Parameter von system() sinnvoll und vorhanden ist auf den Systemen, auf denen Dein Programm läuft.

    cls ist ein interner befehl der command.com bzw cmd.exe
    Es ist sichergestellt, daß system("cls") geht.

    Shiba schrieb:

    Persönlich betrachte ich den Parameter als freundliche, spekulative Annahme. Dein Programm wartet im Ablauf darauf, dass ein Return zurück kommt bzw. der Prozess endet. Das kann je nach Parameter von system eine Neu-Inszenierung von "Warten auf Godot" werden.

    Du redest gar nicht von system("cls"), sondern vor irgendwelchen anderen Aufrufen mit system. Das ist ein großer Unterschied.

    Shiba schrieb:

    Die "bösen" Beispiele, die ich bis jetzt gesehen haben, weigerten sich auch konsequent den Return auszuwerten.

    ???

    Shiba schrieb:

    Der Return kommt übrigens von cmd.exe/coomand.com und muss nicht dem Return eines als Parameter auf gerufenen Programmes entsprechen.

    Naja, ist bei cls nicht soo schlimm: völlig irrelevant.

    Shiba schrieb:

    Du vergibst hiermit die Kontrolle über Deinen Programmfluss und kannst Fehler nicht abfangen oder verarbeiten. Willkommen auf der Dunklen Seite 😃

    Naja, ist bei cls nicht soo schlimm: völlig irrelevant.

    Shiba schrieb:

    Weiterhin hat der neue Prozess eine andere comspec- und path-Variable als der Aufrufende, nämlich die des aufgerufenen ( wenn vorhandenen ) cmd.exe.

    Ist das bei cls ein Problem?

    Shiba schrieb:

    Auch muss man aktuelle Streams flushen oder schliessen bevor man system nutzt.

    Muß man auch bei den API-Methoden.

    Shiba schrieb:

    Das Nutzen betriebssystemspezifischer Hardwarsteuerung(im Thread beschrieben) in eigenen Modulen/Bibliotheken ist sauberer und der Programmierer hält die Kontrolle über das Programm.

    Generell: Ja.
    Bei cls: Eher egal.

    Ich fürchte, es bleiben keine nennenswerten Argumente gegen system("cls") übrig. Nur eines:
    system ist generell schlimm und man vermeidet es, wenn es einfach geht. Bei cls geht es einfach. Also ist das der ideale Trainingsgrund, das mal zu üben.



  • Es sind Argumente gegen sytem().
    Ich meinte die Windows Konsole.
    clrscr finde ich in der conio.h meines Compilers nicht.



  • Shiba schrieb:

    clrscr finde ich in der conio.h meines Compilers nicht.

    Welcher Compiler? Insbesondere: Ist er für DOS und nicht fpr die Win32-Konsole?



  • Unter DOS hatten Borland-Compiler in der conio.h clrscr.

    Bei DOS-Compilern der Mitbewerber wie Microsoft, Zorland/Symantec/Digital-Mars oder Watcom gab/gibt es vergleichbare Funktionen, teilweise in anderen Headern, mit unter Umständen deutlich abweichenden Namen.

    MfG f.-th.



  • Hab das mal für den Digital-Mars Compiler heraus gesucht:

    #include <disp.h>
    
    disp_move(0,0);
    disp_eeop();
    

    das entspricht bei Borland

    clrscr();
    

    funktioniert noch auf dem free bcc 5.5

    Hier mal ein Link:
    http://www.shedai.net/c/new/PCLRSCRN.HOW

    Es gibt auch noch mehrere Tools die den Borland Syntax für andere Compiler zur Verfügung stellen. Beispiel hier aus dem Forum: Improved Console 4.0.
    Es gibt da auch noch andere Werkzeuge 👍

    Viel Spass
    f.-th.



  • Danke für den Link. 🙂



  • Die Visual Studio Compiler haben kein clrscr.
    Wie schon bemerkt der alte Borland und andere schon.
    Aber ich bin auch von Windows Konsolenprogrammen ausgegangen.
    Wenn der Compiler es bietet, kann man es natürlich auch nutzen.



  • @Shiba schau in den Link von mir.
    Die ersten VS-Versionen in den 90ern haben da noch die DOS-Variante. DOS in VS funktionierte nur bis VS 1.5 oder so?

    Wenn ihr das real unter DOS lösen wollt, wie war noch mal der Interrupt? int 10h?
    Da könnt ihr euch auch durch wühlen. Neuere Betriebssysteme erschweren einem ja diese hardwarenahen Lösungen 😉

    Bei aktuellen VS geht das über Windows.h.

    MfG f.-th.



  • Da erwischt man sich wieder 😃

    Moderne OS natürlich nur, wenn Windows -> windows.h 🤡
    In Linux natürlich anders.

    MfG f.-th.



  • Danke f.-th. für den Hinweis 🙂
    Mir ging es allein um system() und da lag ich, wie Volkhard schon bemerkte, leicht nebendem Threadthema.



  • Die Visual Studio Compiler haben kein clrscr.

    Wenn der Code dazu nun bei einem anderen Compiler vorliegt, kann man nicht einfach die Datei kopieren und dann #includen?



  • Kannst ja wegen dem Code bei Microsoft nachfragen 👍
    Wenn du den bekommst, startest du die gleiche Frage bei den Borland/Embarcadero. Dann schaust du dir den Quelltext der Bibliotheken an und konstruierst da eine eigene daraus, lässt die von beiden Firmen lizenzieren u.s.w. 🤡
    Oder hast du etwas anderes geplant 😕
    Da geht noch was 😉

    Ich habe ja was von Werkzeugen oder Tools (muss wohl so 🤡 ) geschrieben.
    Da gibt es dann mehrere verschiedene Varianten wie du deinen Lieblingscompiler mit entsprechenden Funktionen nachrüsten kannst.

    MfG f.-th.



  • Thuruk schrieb:

    Die Visual Studio Compiler haben kein clrscr.

    Wenn der Code dazu nun bei einem anderen Compiler vorliegt, kann man nicht einfach die Datei kopieren und dann #includen?

    Ähh ... wenn Du Visual Studio benutzen willst, programmierst Du wohl für Windows. Dann kannst Du einfach die oben gepostete Funktion verwenden.



  • ich habe für meine win-konsolen-anwendung meine sysmte("CLS") befehle durch die funktion auf der ersten seite ersetzt. funktioniert alles auch wunderbar - genau wie es soll.
    aber es gibt immernoch ein problem:
    wenn ich recht schnell hintereinander die konsole leere - wieder beschreibe und wieder leere blinkt die erste bzw ersten zeilen. ich dachte das wäre durch deine funktion behoben.
    gibt es noch eine andere möglichkeit?



  • Was meinst Du mit 'recht schnell'?
    Wenn ich morgens aus dem Haus gehe, mache ich das Licht aus. Wenn es abends dunkel wird, mache ich es wieder an.
    Wenn ich das aber nun im Rhythmus einer halben Sekunde oft hintereinander mache ... dann blinkt es halt ...



  • okay, hier etwas genauer:
    ich habe ein menü mit einer pfeil auswahl geschrieben. funktion: ich setze einen ascii pfeil auf auswahl 1, dann drücke ich die pfeiltaste nach unten.
    dann lösche ich alle ausgaben auf der konsole mit system("cls") und schreibe nun das selbe menü wieder hin, nur das der pfeil nun bei option 2 davor steht, nicht mehr bei der ersten option.
    wenn ich nun schnell die pfeiltasten hoch & runter drücke blinkt die erste zeile in meiner konsole kurz (ms). ich dachte das würde an meinem befehl system("cls") liegen, wegen os-befehl etc. aber mit der funktion auf seite 1 blinkt es immernoch für wenige ms in meiner konsole.

    edit: es blinkt nur die erste zeile. die anderen zeilen, die auch immer gelöscht und wieder ausgegebn werden bleiben konstant stehen.



  • Dafür würde ich nicht den ganzen Bildschirm löschen, sondern nur die Stelle, wo Dein zu löschender Text steht (Dein Ascii-Pfeil). Dann brauchst Du dafür auch nicht den ganzen Bildschirm neu zu beschreiben.

    Wenn ich das richtig verstehe, würde es doch ausreichen:

    Einmal Bildschirm löschen.
    Einmal Menü ausgeben.

    In einer Schleife:
    Ascii-Pfeil an der gewünschten Stelle ausgeben.
    Taste abwarten.
    Ascii-Pfeil an der alten Stelle mit Blanks überschreiben.
    Schleife wieder von vorne.



  • Beispiel:

    #include <windows.h>
    
    void DruckSimpleText(int x, int y, char const *text)
    {
        COORD target = {x, y};
        DWORD written;
    
        WriteConsoleOutputCharacter(GetStdHandle(STD_OUTPUT_HANDLE), text,
                                                strlen(text),
                                                target, &written);
    }
    
    int main()
    {
    	for(int i = 0; i < 10; ++i)
    	{
    		DruckSimpleText(5, i, "===>");
    		Sleep(2000);
    		DruckSimpleText(5, i, "    ");
    	}
    }
    

Anmelden zum Antworten