kostenloser Webspace werbefrei: lima-city


Verständnisfrage zu While-Schleife

lima-cityForumProgrammiersprachenJava

  1. Autor dieses Themas

    fabo

    fabo hat kostenlosen Webspace.

    Guten Abend,

    ich stehe gerade vor einem seltsamen Problem und schätze, dass irgendwer von euch die Lösung kennt :D

    Es geht um Folgendes:

    -
            int a = 0;
            int b = 0;
            
            Scanner keyIn = new Scanner(System.in);
            
            while(a == 0) {
                System.out.print("Bitte geben Sie eine Zahl (größer als 0) ein: ");
                a = (isNumber(keyIn.next()) ? Integer.parseInt(keyIn.next()) : 0);
            }
            
            while(b == 0 || b == a) {
                System.out.printf("Bitte geben Sie eine weitere Zahl (größer als 0 und ungleich %d) ein: ", a);
                b = (isNumber(keyIn.next()) ? Integer.parseInt(keyIn.next()) : 0);
            }


    Ich möchte einfach nur, dass eine Zahl eingegeben und auf Korrektheit überprüft wird (isNumber ist eine eigene Funktion, die lediglich einen entsprechenden Boolean zurück gibt). Sobald a größer als 0 ist, soll die 2. Zahl eingegeben werden können. Die Frage nach den Zahlen wiederum soll so lang gestellt/wiederholt werden, bis man tatsächlich eine Zahl eingibt, oder den Prozess beendet.

    Das funktioniert witzigerweise auch, jedoch muss ich jede Zahl 2x eingeben (Zahl eingeben -> Enter -> Noch einmal eingeben). Erst dann läuft das Ganze weiter.

    Wäre jemand so freundlich, mir den Fehler aufzuzeigen?

    EDIT:

    Okay, bin einen Schritt weiter:

    while(a == 0) {
                System.out.print("Bitte geben Sie eine Zahl (größer als 0) ein: ");
                a = (keyIn.hasNext("[1-9]+") ? Integer.parseInt(keyIn.next()) : 0);
            }
            
            while(b == 0 || b == a) {
                System.out.printf("Bitte geben Sie eine weitere Zahl (größer als 0 und ungleich %d) ein: ", a);
                b = (keyIn.hasNext("[1-9]+") ? Integer.parseInt(keyIn.next()) : 0);
            }


    Jetzt geht's weiter, sobald ich eine Zahl eingebe. Problem jedoch ist, dass sobald ich einen String eingebe, nichts mehr passiert :D

    Beitrag zuletzt geändert: 15.5.2012 22:48:06 von fabo
  2. Diskutiere mit und stelle Fragen: Jetzt kostenlos anmelden!

    lima-city: Gratis werbefreier Webspace für deine eigene Homepage

  3. Moin,

    generell musst Du mehr Abfragen einbauen, um zu prüfen, ob der eingegebene String dem gesuchten Format entspricht.

    Ergo in der äußersten while-Schleife checken, ob dieser Zustand zutrifft. Wenn nicht, Abbruch mit entsprechender Fehlermeldung/Ausgabe. Ansonsten eben weiter durch die if-Abfragen jagen...

    Gruß,
    Pawnee
  4. Autor dieses Themas

    fabo

    fabo hat kostenlosen Webspace.

    Bist du dir da sicher? Denn soweit ich weiß, kann ich das genau so machen, da die Schleife durch keyIn. so lange unterbrochen wird, bis eine EIngabe erfolgt ist. a wird dann wiederum nur > 0, wenn es sich bei der Benutzereingabe tatsächlich um eine Zahl zwischen 1 und X handelt. Nach der Eingabe sollte die Schleife fortgesetzt werden und wenn a == 0, müsste die ganze Geschichte doch eigentlich wiederholt werden?!
  5. Moin,

    Wie willst Du denn bitte unterscheiden, ob ein String oder eine Zahl eingegeben wurde? Irgendwo wirst Du das abfragen müssen.

    Die Schleife wird durch den Scanner unterbrochen, das steht außer Frage, auch wird diese bei Nicht-Erfüllung wiederholt.

    Und laut Deinem aktuellen Code, sollte, ich nenne Sie mal Schleife a, diese auch weiterlaufen.

    Gruß,
    Pawnee
  6. Autor dieses Themas

    fabo

    fabo hat kostenlosen Webspace.

    Wie willst Du denn bitte unterscheiden, ob ein String oder eine Zahl eingegeben wurde? Irgendwo wirst Du das abfragen müssen.


    Durch Scanner.hasNext

    Gibt selbiges true zurück, wandle ich die Eingabe in einen Integer um und springe zur nächsten Schleife. Wenn nicht, setze ich a = 0 und nach meinem Verständnis sollte die Schleife wiederholt werden.

    Genau hier liegt aber mein Problem -

    while(a == 0) {
    			System.out.print("Bitte geben Sie eine Zahl (größer als 0) ein: ");
    			a = (keyIn.hasNext("[1-9]+") ? Integer.parseInt(keyIn.next()) : 0);
    		}


    Gebe ich hier 0 oder einen String ein, passiert nichts mehr. Gebe ich jedoch eine Zahl ein, geht's vorwärts.

    Beitrag zuletzt geändert: 15.5.2012 23:37:06 von fabo
  7. Moin,

    das scheint wohl an .hasNext() zu liegen. Auch bei mir blockt Dein Beispiel durchgängig, sobald etwas anderes als [1-9] eingegeben wird. Keine Ahnung, warum das so ist ... wirst Du wohl umbauen und einen eigenen Matcher verwenden müssen.

    Gruß,
    Pawnee
  8. e******a

    Das Problem ist, dass
    hasNext()
    nicht einen neuen Wert anfordert. D.h. du hast dann im Grunde eine endlose Iteration.
    Ich empfehle dir also eher sowas:
    while (a == 0) {
        System.out.print("Bitte geben Sie eine Zahl (größer als 0) ein: ");
        if (keyIn.hasNextInt()) {
            a = keyIn.nextInt();
        } else {
            keyIn.next();
        }
    }
    
    while (b == 0 || a == b) {
        System.out.printf("Bitte geben Sie eine weitere Zahl (größer als 0 und ungleich %d) ein: ", a);
        if (keyIn.hasNextInt()) {
            b = keyIn.nextInt();
        } else {
            keyIn.next();
        }
    }
  9. Autor dieses Themas

    fabo

    fabo hat kostenlosen Webspace.

    Das funktioniert sogar :D Vielen Dank.

    Jetzt muss ich aber leider noch etwas fragen:

    while(true) {        
                System.out.print("blabla\n\n");
                System.out.print("So weit verstanden? [j(a), n(ein), e(nde)] ");
                
                if(keyIn.hasNext("j|ja"))
                    break;
                else if(keyIn.hasNext("n|nein"))
                    continue;
                else if(keyIn.hasNext("e|ende"))
                    System.exit(0);
            }


    Gebe ich e oder ende ein, wird die Ausführung wie erwartet abgebrochen. Gebe ich j oder ja ein, springt das Programm wie erwartet zur nächsten Schleife (obgleich es dort ein anderes Problem gibt...). Schreibe ich jedoch n oder nein, lande ich in einer Endlosschleife.

    Woran kann das liegen? Wieder so ein Scanner-Problem?
  10. hackyourlife

    Moderator Kostenloser Webspace von hackyourlife

    hackyourlife hat kostenlosen Webspace.

    fabo schrieb:
    Woran kann das liegen? Wieder so ein Scanner-Problem?
    Das liegt daran, dass du nur prüfst ob der Buchstabe vorhanden ist, aber du liest ihn nicht ein.
  11. Autor dieses Themas

    fabo

    fabo hat kostenlosen Webspace.

    Muss ich das denn? Ich meine... Die Eingabe soll so lange wiederholt werden, wie der Benutzer nicht e/ende oder j/ja eingegeben hat. Auch hier sagt mein Verstand, dass die Schleife eigentlich wiederholt werden sollte, wenn der Benutzer n/nein eingibt. Wobei ich eine kleine Änderung eingeführt habe:

    while(true) {
                System.out.print("blabla\n\n");            
                System.out.print("So weit verstanden? [j(a), n(ein), e(nde)] ");
                
                if(keyIn.hasNext("j|ja"))
                    break;
                else if(keyIn.hasNext("e|ende"))
                    System.exit(0);
                else
                    continue;
            }


    Sonst hätte ich spätestens dann Probleme bekommen, wenn der Benutzer weder ja, noch nein, noch Ende eingegeben hätte.

    Dennoch erklärt dies nicht, warum sich mir auf einmal eine Endlosschleife zeigt, wenn ich nein eingebe.
  12. hackyourlife

    Moderator Kostenloser Webspace von hackyourlife

    hackyourlife hat kostenlosen Webspace.

    fabo schrieb:
    Dennoch erklärt dies nicht, warum sich mir auf einmal eine Endlosschleife zeigt, wenn ich nein eingebe.
    Doch...
    Du schaust mit
    hasNext
    ob der Benutzer einen bestimmten Wert eingegeben hat.
    Dieser eingegebene Wert bleibt aber im Puffer stehen... erst wenn du den Wert liest kommt der nächste eingegebene Wert in den Puffer, der dann mit
    hasNext
    wieder überprüft werden kann.
    Du musst also bei jedem Schleifendurchlauf den eingegebenen Wert lesen.

    Solange du jedenfalls nichts liest bleibt im Puffer der gleiche Wert bestehen und dein
    hasNext
    wird immer das gleiche Ergebnis liefern.
  13. Autor dieses Themas

    fabo

    fabo hat kostenlosen Webspace.

    Entschuldige meine blöde Frage, aber wie müsste das auslesen denn aussehen?! Und warum funktionieren ja und ende? Ich beginne Java zu hassen :D

    EDIT:

    So scheint es zu gehen:

    while(true) {
    			System.out.print("blabla");
    			System.out.print("So weit verstanden? [j(a), n(ein), e(nde)] ");
    			
    			if(keyIn.hasNext("j|ja")) {
    				break;
    			}
    			else if(keyIn.hasNext("e|ende")) {
    				System.exit(0);
    			}
    			else {
    				keyIn.next();
    				continue;
    			}
    		}


    Das Ganze hat aber einen Haken: Setze ich die selbe Schleife darunter und springe zu selbiger, in dem ich j bzw. ja eingebe, wird die Eingabe bei der nächsten Schleife direkt übersprungen und das Programm wird beendet?

    Beitrag zuletzt geändert: 17.5.2012 15:11:21 von fabo
  14. hackyourlife

    Moderator Kostenloser Webspace von hackyourlife

    hackyourlife hat kostenlosen Webspace.

    fabo schrieb:
    Das Ganze hat aber einen Haken: Setze ich die selbe Schleife darunter und springe zu selbiger, in dem ich j bzw. ja eingebe, wird die Eingabe bei der nächsten Schleife direkt übersprungen und das Programm wird beendet?
    Weißt du auch warum?
    Nachdem ein richtiger Wert eingegeben wurde (j oder n oder so) wird die Schleife beendet und der Wert bleibt im Puffer.

    Du müsstest nach deiner Schleife nochmals mit
    keyIn.next();
    den Puffer leeren.
  15. Autor dieses Themas

    fabo

    fabo hat kostenlosen Webspace.

    while(true) {
    			keyIn.nextLine(); // Puffer leeren
    
                            // ...


    Eher so, oder? Denn wenn ich next() auslese, erwartet das Ganze doch einen String, richtig? Da ich meine Eingabe ja mit Enter bestätigen muss, ist die letzte Eingabe aber Return und kein String. Oder vertu ich mich da gerade?
  16. Zum einen kannste das else continue stecken lassen, weil nachher keine Anweisungen mehr kommen.
    Zum anderen nehme ich an, dass der Scanner den Inhalt dann nicht aus dem Buffer löscht, also solltest du den Buffer einfach mal flushen.
    Zum Beispiel dann:
    System.in.flush()
    Aber bin mir nicht sicher, ob das klappt.
  17. hackyourlife

    Moderator Kostenloser Webspace von hackyourlife

    hackyourlife hat kostenlosen Webspace.

    reimann schrieb:
    Zum anderen nehme ich an, dass der Scanner den Inhalt dann nicht aus dem Buffer löscht, also solltest du den Buffer einfach mal flushen.
    Zum Beispiel dann:
    System.in.flush()
    Aber bin mir nicht sicher, ob das klappt.
    Mit Puffer meine ich den Eingabepuffer, in dem der nächste Token steht, und dieser wird mit next gelöscht und der nächste Token wird in den Puffer verschoben.

    fabo schrieb:
    Eher so, oder?
    Fast...

    Vielmehr so:
     		while(true) {
    			System.out.print("blabla");
    			System.out.print("So weit verstanden? [j(a), n(ein), e(nde)] ");
    			
    			if(keyIn.hasNext("j|ja")) {
    				break;
    			} else if(keyIn.hasNext("e|ende")) {
    				System.exit(0);
    			} else {
    				keyIn.next();
    			}
    		}
    		keyIn.next();


    Beitrag zuletzt geändert: 17.5.2012 15:34:48 von hackyourlife
  18. Autor dieses Themas

    fabo

    fabo hat kostenlosen Webspace.

    Ich hab's jetzt mal so ausprobiert:

    while(true) {
                keyIn.nextLine(); // Puffer leeren
                
                System.out.printf("Blabla\n\n", a, b);
                System.out.print("So weit verstanden? [j(a), n(ein), e(nde)] ");
                
                if(keyIn.hasNext("j|ja")) {
                    break;
                }
                else if(keyIn.hasNext("e|ende")) {
                    System.exit(0);
                }
                else {
                    continue;
                }
            }


    Das scheint zu funktionieren und auch nur deswegen, weil next() tatsächlich die Eingabe von Enter zu ignorieren scheint. Ferner habe ich keyIn.nextLine(); aus dem Grunde direkt an den Anfang der Schleife gepackt, weil mir das min. 1 Zeile erspart, da ich sowohl bei EIngabe von ja, als auch von nein darauf angewiesen bin, den Puffer zu leeren. Sonst lande ich ja wieder in einer Endlosschleife.

    Beitrag zuletzt geändert: 17.5.2012 15:38:36 von fabo
  19. hackyourlife

    Moderator Kostenloser Webspace von hackyourlife

    hackyourlife hat kostenlosen Webspace.

    fabo schrieb:
    Ferner habe ich keyIn.nextLine(); aus dem Grunde direkt an den Anfang der Schleife gepackt, weil mir das min. 1 Zeile erspart, da ich sowohl bei EIngabe von ja, als auch von nein darauf angewiesen bin, den Puffer zu leeren. Sonst lande ich ja wieder in einer Endlosschleife.
    Das löscht aber vor dem ersten Schleifendurchlauf auch schon den Puffer und lässt nach dem letzten Schleifendurchlauf den Puffer gefüllt... ob das wirklich das ist was du wolltest?
  20. Autor dieses Themas

    fabo

    fabo hat kostenlosen Webspace.

    Hm... Okay. Ich merke zumindest, in welche Richtung das Ganze geht und denke, dass ich das Problem jetzt lösen kann :D Ich danke dir für die Hilfe :)
  21. Diskutiere mit und stelle Fragen: Jetzt kostenlos anmelden!

    lima-city: Gratis werbefreier Webspace für deine eigene Homepage

Dir gefällt dieses Thema?

Über lima-city

Login zum Webhosting ohne Werbung!