Endlosschleife überspringt std::cin



  • Hi, bei diesem Programm werden Zahlen eingelesen und nach Drücken von Return ausgegeben.
    Wird jedoch ein Buchstabe eingegeben, dann wird immer wieder eine Zahl ausgegeben und
    es ist nicht mehr möglich, eine neue Eingabe zu machen. Diese Zahl ist bei erstmaliger Eingabe
    eines Buchstaben 1. Wurde vorher eine Zahl eingegeben, ist es diese Zahl. Das ist zum Beispiel
    dann ein Problem, wenn man Fehler abfangen möchte. Warum verhält sich das Programm so?

    #include <iostream>
    
    using namespace std;
    
    int main()
    {
        int Var;
    
        for(;;){
    
            cin>>Var;       //Wird hier ein Buchstabe eingegeben,
                            //lässt sich Var nicht mehr ändern
                            //und wird ständig ausgegeben
    
            cout<<Var<<endl;
        }
    
        return 0;
    }
    


  • Achtung, das folgende ist nur eine Vermutung und solltest du nicht zu Ernst nehmen...
    Und zwar denke ich das Problem entsteht durch den Eingabepuffer. Wenn du eine Zahl eingibst dann landet diese vorerst im Eingabepuffer. Drückst du Enter, landet auch ein \n dort. Also angenommen du drückst 3 und dann Enter, so liegt im Eingabepuffer 3 \n. std::cin versucht jetzt einen Typ int vom Puffer in Var zu übergeben. Die 3 wandert also aus dem Eingabepuffer raus und \n bleibt drin liegen. std::cin hat nun getan, was es sollte und Var wird ausgegeben. Deine 3 erscheint.

    Nun das Problem mit dem Buchstabe:
    Du drückst b und Enter. Im Puffer liegt nun also b \n. std::cin versucht nun wieder einen Typ int vom Puffer in Var zu übergeben. Aber es findet keinen int. Also bleibt b \n im Puffer liegen. std::cout gibt dir nun Var aus. In Zeile 7 steht

    int Var;
    

    Schon bei diesem Schritt wird Speicher reserviert. Allerdings wird Var nicht von std::cin geändert. Was also in Var nun herum liegt ist zufällig. Deshlab gibt dir std::cout irgendetwas anderes aus. Sobald die Schleife von vorn startet und zu std::cin kommt, merkt std::cin, dass da schon was im Eingabepuffer liegt. Deshalb liest es nicht neu ein. Dann versucht es wieder einen int zu finden, den es aber nicht findet, weil nach wie vor b \n drin liegt. Und so weiter und so weiter.

    Ich könnte es mir so ähnlich vorstellen. Bin aber auch gespannt, was jemand mit Ahnung hier Antwortet. Vielleicht lieg ich mit Allem auch komplett daneben. Bitte korrigiert mich, falls ich etwas komplett falsch erklärt habe, ich möchte auch draus lernen 🙂



  • http://www.cplusplus.com/reference/ios/ios/fail/

    Sobald der Typ nicht stimmt, wird das failbit gesetzt und cin versucht erst gar nicht eine erneute Eingabe einzuleiten.

    Mit

    std::cin.clear()

    Kannst du das failbit wieder zurücksetzen, musst aber anschließend alle bösen Zeichen im Buffer löschen.

    Das kannst du dann mit

    std::cin.ignore()

    erreichen. Wie das genau geht, kannst du hier nachlesen

    http://www.cplusplus.com/reference/istream/istream/ignore/



  • Ah, vielen Dank. Gut die richtige Antwort jetzt zu kennen. Auch wenn ich eigentlich nicht die Frage gestellt habe 🙂



  • 👍


Log in to reply