continue Befehl bei do-While Schleife



  • Hallo zusammen, ich habe eine Frage zu folgender do-while Schleife. Ich benutze sie um die eingegebene Zahl zu kontrollieren (ganze Zahl und überhaupt eine Zahl).
    Wir sollten den Wert als double einlesen sonst hätte ich direkt eine Integer-Variable gewählt.

    Das ganze funktioniert auch soweit bis auf die Tatsache, dass er aus der Schleife springt wenn ich z.b. einen Buchstabe eingebe, obwohl er doch eigentlich wegen dem continue-Befehl wieder zum Anfang der Schleife springen müsste.
    Wenn ich eine Kommazahl eingebe, springt er wieder nach oben.

    Funktioniert der continue-Befehl überhaupt bei do-while Schleifen? 😕
    Hier ist der Code

    Vielen Dank 🙂

    do{
    
     double eingabe = 0;
     cin >> eingabe;
    
     double nachkommaBereich = eingabe-static_cast<int>(eingabe);
     const double DEpsilon =numeric_limits<double>::epsilon();
    
     if (nachkommaBereich >=DEpsilon) {
         cout << "Bitte nur ganze Zahlen eingeben"<<endl;
         continue;}
     else if ((!cin.bad()&& cin.eof()))  {
         //warum springt er hier raus??
         cout<<"Bitte nur Zahlen eingeben"<<endl;
         continue;}
    
     }while(cin);
    

  • Mod

    continue springt nicht zum Anfang einer Schleife sondern an deren Ende, als nächstes wird folglich die Schleifenbedingung ausgewertet.

    do{
    
     double eingabe = 0;
     cin >> eingabe;
    
     double nachkommaBereich = eingabe-static_cast<int>(eingabe);
     const double DEpsilon =numeric_limits<double>::epsilon();
    
     if (nachkommaBereich >=DEpsilon) {
         cout << "Bitte nur ganze Zahlen eingeben"<<endl;
         continue;}
     else if ((!cin.bad()&& cin.eof()))  {
         //warum springt er hier raus??
         cout<<"Bitte nur Zahlen eingeben"<<endl;
         continue;}
    continue_jumps_here:
     }while(cin);	
    break_would_jump_to_here:
    


  • Okay dann habe ich continue falsch verstanden. Welcher Befehl würde denn für meinen Zweck der richtige sein? 😕
    Also das wieder zum Anfang der Schleife gesprungen wird und diese nicht verlassen wird.

    Was ich auch nicht an meinem Code verstehe ist folgendes:
    else if ((!cin.bad()&& !cin.eof()))

    Wieso muss ich beides negieren? Für mich wäre es ohne Negation logisch.



  • Philipp2706 schrieb:

    Welcher Befehl würde denn für meinen Zweck der richtige sein? Also das wieder zum Anfang der Schleife gesprungen wird und diese nicht verlassen wird.

    Befehl für Sprung zum Schleifenanfang kenne ich nicht (außer mit goto und Sprungmarke). Das Problem ist auch nicht, daß mit continue zum Schleifenende gesprungen wird, sondern es liegt daran, daß nach Eingabe eines Buchstaben die Bedingung zum Beenden der Schleife erfüllt ist. Ggf. ist while(cin) hier eine unglückliche Wahl. Genauer: Wenn, wie im Code gefordert, eine als Typ double gültige Zahl eingegeben wird, dann liefert cin in while(cin) einen Wert ungleich Null, was true entspricht. Also wird die Schleife nochmal durchlaufen. Aber nach Buchstabeneingabe liefert cin in while(cin) den Wert Null, was false entspricht. In diesem Fall wird also die Schleife beendet.

    if ((!cin.bad()&& !cin.eof()))

    Ja, verstehe ich auch nicht. cin.bad() und cin.eof() liefern bei mir immer false, egal was ich eingebe. Ich habe dann den Code umgeändert und cin.fail() verwendet. Damit läuft es besser, mögl.weise geht es auch mit cin.good(). Wichtig scheint auch zu sein, im Fehlerfall (Buchstabeneingabe) zuerst die internen Fehlerflags mit cin.clear() zu löschen und danach den Streampuffer zu leeren (z.B. durch Einlesen in ein char-Array). LG



  • #include <string>
    #include <iostream>
    #include <sstream>
    using namespace std;
    
    /*
     failbit wird bei Logikfehler gesetzt: Wenn
     -die Daten nicht zum geforderten Datentypen passen.
     -versucht wird, etwas zu lesen, das es nicht gibt.
     -das Stream-Objekt nicht mit der angegebenen Datei verbunden werden konnte.
    	(Achtung: Wird nicht gesetzt, wenn man vergisst, eine Datei anzugeben. Falle: !stream ---> .is_open() verwenden)
     */
    
    /*
     eofbit wird gesetzt, wenn versucht wird, über das letzte Zeichen hinaus zu lesen.
     */
    
    /*
     badbit wird bei Nicht-Logikfehler gesetzt: Wenn z.B. eine Exception fliegt.
     */
    
    /*
     Nicht-zeichenweise lesen: operator>> --> ignoriert standardmäßig Leerzeichen, Tabs und Zeilenumbrüche.
     Zeichenweise lesen: get --> ignoriert sie nicht.
     */
    
    /*
     Wenn fail oder bad true ist, schlagen alle weiteren Leseoperationen fehl.
     Du musst den stream dann resetten (clear) und ggf. Zeichen verwerfen (ignore).
     */
    
    void status(const istringstream& iss)
    {
    	cout << endl;
    	cout << "good = " << iss.good() << endl; // true, wenn eof und bad und fail alle false sind.
    	cout << "bad  = " << iss.bad()  << endl;
    	cout << "fail = " << iss.fail() << " == " << !iss << endl; // ist das Gleiche wie !iss
    	cout << "eof  = " << iss.eof()  << endl;
    }
    
    int main()
    {
    	char c;
    	int i;
    
    	cout << endl << "1. Erwartung";
    	{
    		istringstream iss( "A 1"); // Simuliert eine Datei
    		iss >> i;
    		status( iss ); // fail=true, da int erwartet, aber char bekommen.
    	}
    
    	cout << endl << "2. Zeichenweise lesen";
    	{
    		istringstream iss( "A 1");
    		iss.get(c);
    		iss.get(c);
    		iss.get(c); // Nun wurden alle Daten gelesen.
    		status( iss ); // good=true
    		iss.get(c);
    		status( iss ); // eof=true, da über das Ende gelesen. fail=true, es wurde versucht etwas zu lesen, das es gar nicht gibt.
    	}
    
    	cout << endl << "3. Nicht-zeichenweise lesen";
    	{
    		istringstream iss( "A 1");
    		iss >> c >> i; // Nun wurden alle Daten gelesen.
    		status( iss ); // Nur eof=true. fail=false, es wurde nicht über das Ende hinausgelesen.
    	}
    }
    

Log in to reply