Importer:Error:WasEmpty



  • Hallo Forum!

    Ich scheitere gerade grandios an einer halbwegs soliden Eingabeprüfung. Wenn man danach googlet, stellt man schnell fest, dass das gerade unter Einsteigern ein "beliebtes" Problem ist, aber eine wirklich brauchbare Lösung finde ich entweder nicht, oder ich verstehe sie nicht richtig.

    Die Situation ist folgende: Ich will abfragen, wie viele Spieler (zwei bis maximal vier) an einem Spiel teilnehmen sollen. Überprüfen will ich nun a) ob die Eingabe tatsächlich eine Ziffer ist und b) ob sie im Bereich von 2 bis 4 liegt. Ist beides nicht der Fall, soll die Abfrage erneut auftauchen.

    Ich habe das mit zwei if-Abfragen versucht, in denen einmal isdigit() oder alternativ cin.fail() abgefragt wird und einmal auf den Bereich getestet wird. Ich habe dabei mit cin.ignore() und cin.clear() rumprobiert, aber das Ergebnis war bei jeder Variante entweder so, dass beide if-Abfragen als 'true' gewertet wurden oder so, dass der Prompt "Anzahl Mitspieler (2-4): " in einer Endlosschleife ausgegeben wurde.

    Ich bin gerade ein bisschen ratlos, und bevor ich hier noch stundenlang nach dem trial-and-error-Prinzip Codebausteine hin- und herschiebe, wollte ich mal nach einem einigermaßen vernünftigen Beispiel / Vorschlag fragen.



  • while (!(std::cin >> number) || number < 2 || number > 4)
    {
    	std::cin.clear();
    	std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
    }
    

    Heißt:
    Solange das Einlesen von Ziffern nicht klappt oder die Ziffer nicht zwischen 2 und 4 ist:
    Lösche den Fehlerzustand im Stream, lösche alle Zeichen aus dem Puffer bis '\n' auftaucht; std::numeric_limits braucht den Header limits.



  • Danke schonmal, Nathan. Das funktioniert. Wenn ich aber meinen Prompt haben will, mss ich den jetzt einmal *vor* der Schleife ausgeben und einmal am *Ende* der Schleife. Das finde ich nicht schön.

    Ich habe also versucht, die ganze Konstruktion umzudrehen und in eine do-while-Schleife zu packen - dann funktioniert es aber nicht mehr. Ich kann eingeben, was ich will, das Programm läuft einfach und läuft und läuft, als würde es permanent auf eine Eingabe warten.


  • Mod

    while (promptausgabe(), !(std::cin >> number) || number < 2 || number > 4)
    

    Wenn du aber eine Text-GUI nachprogrammieren möchtest, wirst du bald feststellen, dass das Konzept der IO-Streams dafür nicht geeignet ist. Du bist gerade schon dabei, die ersten Schwierigkeiten zu entdecken. Und diese Schwierigkeiten sind auch nicht endgültig zu lösen, da die beiden Konzepte fundamental inkompatibel sind. Du solltest dir besser eine spezialisierte Bibliothek für Text-GUIs ansehen (oder gleich eine "richtige" GUI? Das wäre kein großer Unterschied). Oder dich fragen, ob das für dein Programm wirklich wichtig ist oder bloß Bling-Bling.



  • @SeppJ - klar, an den Komma-Operator hatte ich überhaupt nicht gedacht. Funktioniert wunderbar, vielen Dank!

    Zu deinen grundsätzlichen Anmerkungen: Ich bin einfach noch lange nicht weit genug, um mich mit UIs oder gar GUIs zu befassen. Das sind bisher alles nur Fingerübungen. Deute ich deine Ausführungen aber dahin gehend richtig, dass es mit Standard-C++ und auf der Konsole robuster als Nathans Codeschnippsel auch gar nicht werden kann? Also, dass es nicht an mangelnden Kenntnissen von mir als Anfänger liegt, sondern grundsätzlich auf dieser Ebene nicht besser geht?


  • Mod

    dennis.cpp schrieb:

    Deute ich deine Ausführungen aber dahin gehend richtig, dass es mit Standard-C++ und auf der Konsole robuster als Nathans Codeschnippsel auch gar nicht werden kann? Also, dass es nicht an mangelnden Kenntnissen von mir als Anfänger liegt, sondern grundsätzlich auf dieser Ebene nicht besser geht?

    Ja. Schon das Konzept der Konsole kommt in streng standardkonformem C++ gar nicht vor. Dein Programm läuft bloß zufällig in einer Konsole an sich kennt es aber bloß Ein- und Ausgabeströme und denen ist es egal, wo die Zeichen herkommen oder landen. Hier kommen die Daten eben von einer Tastatur und landen auf dem Bildschirm, aber genau das gleiche Programm kannst du auch ohne Änderung zwischen ein Modem als Eingabegerät und einen Drucker als Ausgabegerät schalten. Und dann merkst du schon, dass ein Eingabeprompt da irgendwie nicht mehr so viel Sinn macht.


Log in to reply