Problem mit cin.fail() in einer Schleife



  • while ( !bError );
    


  • #include <exception>
    
    throw std::bad_argument ("DAS WAR KEINE ZAHL!");
    

    oder so was gabs da doch ^^

    bb

    PS: Caps macht die Fehlermeldung auch nicht besser ^^



  • while(!bError);
    

    bewirkt ja gerade das, was ich nicht haben möchte: nämlich dass die Schleife weiterläuft, wenn die Eingabe korrekt ist.

    Die Libary<exception> und der Namespace std sind in C++ ja standardmäßig schon mit eingebunden, das hilft mir also auch nicht weiter. 😕

    Ich glaube eher, es liegt daran, das im Puffer vom cin immer noch etws steht. Kennt jemand den Befehl, den Puffer zu lehren? fflush und flush funktionieren nicht ohne weiteres.

    PS:

    Dann vielleicht rot blinkende Schrift? ^^

    cout<<"\033[5;38mDas war keine Zahl!\033[0m"<<endl;
    


  • Achso. Ja, das Problem sind die verbliebenen "Eingabereste". Die müssen raus.
    Dafür gibts einige Ansätze, wobei viele davon nicht wirklich Portabel (aber fast überall funktionsfähig) sind (=> .ignore()).



  • Ja, der Ansatz ist gut, aber ignore, clear und konsorten haben auch nix geholfen.



  • 1nf1n1tY schrieb:

    Ja, der Ansatz ist gut, aber ignore, clear und konsorten haben auch nix geholfen.

    So tut's für mich:

    int iMenu;
    bool bError=0;
    
    do
    {
        try
        {
            cout<<"Was soll gesucht werden: ";
            if(!cin || !(cin>>iMenu))
            {
                cin.clear();
                cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
                bError=1;
                throw ( "DAS WAR KEINE ZAHL!" );
            }
        }
        catch ( const char* sFM )
        {
            cout<<sFM<<endl;
        }
    }
    while ( bError );
    

    Siehe auch hier

    EDIT: Natürlich fehlt da noch das Zurücksetzen des Fehlerflags (bError)!!



  • Hey, das ist es! Danke! ^^



  • Vermutlich wäre das Vorbeugen, gegen einen solchen Fehler, besser. Also immer in einen Stringpuffer einlesen (std::getline( ... )) und Letzteren dann in ein int konvertieren.



  • David_pb schrieb:

    Vermutlich wäre das Vorbeugen, gegen einen solchen Fehler, besser. Also immer in einen Stringpuffer einlesen (std::getline( ... )) und Letzteren dann in ein int konvertieren.

    Und dann?

    Mußt du trotzdem überprüfen, ob der/die/das int richtig gelesen werden konnte:

    std::string str;
    std::getline(std::cin, str);
    std::stringstream strm;
    strm << str;
    if(str >> iMenu)
       OK();
    else
       NOT_OK();
    

    ??



  • Ja, das ist auch eine Lösung aber damit wird das Problem einfach umgangen, statt es an der Wurzel zu Packen.



  • @bladerunner10:
    Das ursprüngliche Problem war ja, dass, nach einer Fehleingabe, das Programm in einer Endlosschleife hingen blieb. Das kann vermieden werden in dem man gegen diese Situation vorbeugt.

    @1nf1n1tY:
    Dafür ist die Lösung aber portabel. 🙂



  • Aber dann hat man keine Gelegenheit, aus der Lösung des Eigentlichen Problems zu lernen.


Anmelden zum Antworten