Problem mit cin.fail() in einer Schleife
-
Hallo erstmal!
Ich habe ein Problem mit der Methode cin.fail(). Diese Methode soll mit Hilfe von try-catch falsche Eingaben abfangen.Das ganze ist in einer Schleife. Sobald der throw ausgelöst wird, hängt sich das Programm in einer Endlosschleife auf. Wie kann ich das verhindern? Vielen Dank im Voraus!
Hier der Quelltext:
int iMenu; bool bError=0; do { try { cout<<"Was soll gesucht werden: "; cin>>iMenu; if ( cin.fail() ) { bError=1; throw ( "DAS WAR KEINE ZAHL!" ); } } catch ( const char* sFM ) { cout<<sFM<<endl; } } while ( bError );
-
Dieser Thread wurde von Moderator/in GPC aus dem Forum Andere GUIs - Qt, GTK+, wxWidgets in das Forum C++ verschoben.
Im Zweifelsfall bitte auch folgende Hinweise beachten:
C/C++ Forum :: FAQ - Sonstiges :: Wohin mit meiner Frage?Dieses Posting wurde automatisch erzeugt.
-
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.