Programmabsturz durch Fehleingabe verhindern
-
Hey Leute,
ich hab mal wieder ne Frage!Also wenn ich eine int variable einlesen lass und der Benutzer zb.: ein buchstabe eingibt gibt es ja sowas wie einen Programmabsturz!
Wie kann ich das verhindern..
ich hab mir das so gedacht!while(true) { cout <<"Geben Sie die Stufe an: "; cin >> stufe; if(!(cin >> stufe)) { cout<<endl; cerr <<"Fehler bei Eingabe"<<endl; getch(); } if(cin.bad()) { cerr<<"Fehler bei Eingabe!"<<endl; getch(); } if(cin.fail()) {cerr<<"Fehler bei Eingabe!"<<endl; getch(); } else break; system("cls"); }allerding wenn ich das so Mache bekomme ich die Fehlermeldungen angezeigt dann aber er lässt mich dann nicht nocheinmal erneut die zahl eingeben er zeigt mir dann nur immerwieder die Fehlermeldungen an!
was mache ich falsch?
oder was kann ich anders machen!mfg
danke schon mal!

-
Fehlerflags zurücksetzen:
if(!cin.good()) { //Fehler beheben cin.clear(); }
-
Wenn das failbit eines Streams erstmal gesetzt wurde, muss man es erst wieder mit clear() löschen, bevor man wieder aus dem Stream lesen kann. Doch Vorsicht: Die Zeichen die zuvor für den Fehler gesorgt haben, sind dann immer noch im Stream (da sie ja nicht ausgelesen wurden), man sollte daher danach noch ein paar Zeichen aus dem Stream mittels ignore() überspringen (je nach Anwendungsfall eines oder alle verbleibenden Zeichen).
-
while(true) { cout <<"Geben Sie die Stufe an: "; cin >> stufe; if(!(cin >> stufe)) { cout<<endl; cerr <<"Fehler bei Eingabe"<<endl; cin.clear(); getch(); } if(cin.bad()) { cerr<<"Fehler bei Eingabe!"<<endl; cin.clear(); getch(); } if(cin.fail()) {cerr<<"Fehler bei Eingabe!"<<endl; cin.clear(); getch(); } else break; system("cls"); }okay so siehts jetzt aus allerdings lässt er mich immernochnicht wieder eingeben! stattdessen geht er einfach aus der schleife raus und macht mit dem resst weiter wobei dann nur müll rauskommt....
was nun?
achja und kannst du das mit dem ignore() bissl erläutern bin noch anfänger ^^mfg
danke erstmal bis hier hin^^
-
Deine zweite und dritte if-Abfrage sind überflüssig, da du schon in der ersten auf alle Flags prüfst - da du die Flags aber schon zu Beginn zurücksetzt, sind sie immer false und daher wird das zu der letzten Abfrage gehörende else immer aufgerufen.
achja und kannst du das mit dem ignore() bissl erläutern bin noch anfänger ^^
http://www.cplusplus.com/reference/iostream/istream/ignore/
Mit ignore kannst du die fehlerhaften Zeichen aus dem Eingabestream entfernen.cin.ignore(numeric_limits<streamsize>::max(), '\n')würde die gesamte restliche Eingabe verwerfen.
btw: Arbeite an deiner Formatierung. Dann wäre dir das mit dem else wahrscheinlich selber aufgefallen.
-
Okay da ich keine ahnung hab was die mir auf der Seite erklären möchten habe ich das einfach mal so einkopiert wie du es mir geschrieben hast...
resultat....
--->Fehler 61 error C2065: 'numeric_limits': nichtdeklarierter Bezeichner c:\users\splinter\documents\visual studio 2008\projects\ogamerechner\ogamerechner\rechner beta.cpp 450
--->
Fehler 62 error C2275: 'std::streamsize': Ungültige Verwendung dieses Typs als Ausdruck c:\users\splinter\documents\visual studio 2008\projects\ogamerechner\ogamerechner\rechner beta.cpp 450
--->
´Fehler 64 error C2589: '(': Ungültiges Token auf der rechten Seite von '::' c:\users\splinter\documents\visual studio 2008\projects\ogamerechner\ogamerechner\rechner beta.cpp 450
--->
Fehler 65 error C2059: Syntaxfehler: '::' c:\users\splinter\documents\visual studio 2008\projects\ogamerechner\ogamerechner\rechner beta.cpp 450
-
Den gesamten Streampuffer entleerst du so:
std::cin.sync(); // "Synchronisiere" den Stream // oder std::cin.ignore(std::cin.rdbuf()->in_avail()); // ignoriere die Anzahl an Zeichen im Puffer
-
std::cin.ignore(std::cin.rdbuf()->in_avail());---okay das funktioniert super bis auf dass ich jetzt wenn ich eine fehleingabe mach zb. ein buchstabe .
zeigt er mir meine Fehlermeldung an ....dann werd ich wieder aufgefordert einzugeben ich geb ein ---> "2"
was ja richtig ist für ein int-wert.
doch das "nimmt er nicht wahr" dann geb ich einfach nochmal 2 an und dann " nimmt er es wahr" .....warum ist das so???while(true) { cout <<"Geben Sie die Stufe an: "; cin >> stufe; if(!(cin >> stufe)) { cout<<endl; cerr <<"Fehler bei Eingabe"<<endl; cin.clear(); std::cin.ignore(std::cin.rdbuf()->in_avail()); getch(); } else break; system("cls"); }EDIT: Habs schon rausgefunden sorry^^ !
-
Ad aCTa schrieb:
Den gesamten Streampuffer entleerst du so:
std::cin.sync(); // "Synchronisiere" den Stream // oder std::cin.ignore(std::cin.rdbuf()->in_avail()); // ignoriere die Anzahl an Zeichen im PufferDieses Verhalten ist leider nicht garantiert, da in_avail nicht die Anzahl der restlichen Zeichen im Eingabepuffer zurückgibt, sondern die Mindestzahl der verfügbaren Zeichen. Leider wird das (zumindest bei vielen GCC-Versionen) ziemlich wörtlich genommen, wodurch in_avail() dort sehr oft 0 zurückgibt. Auch in Fällen in denen man einen anderen Wert erwarten würde.