Nichtzahlen Eingabe abfangen
-
Ok vielen Dank schonmal..war schon eine riesen Hilfe
Nur würde ich das gerne mit diesem try, catch exception handling machen, weil das erstens unser Lehrer gerne sieht und zweitens ich da später noch mehrere exceptions anhängen muss. hab das nun so gemacht:i=1; while (i) { try { if(!(cin>>time_rndarrive )){ throw int(); } else { i=false; cin.clear(); //damit ich auch zb 15min eingeben kann cin.ignore(numeric_limits<int>::max(),'\n'); } } catch(const int ) { cout << "Fehler! Eingegebener Wert war keine Zahl! Bitte nochmal eingeben: "; cin.clear(); cin.ignore(numeric_limits<int>::max(),'\n'); } }
Das funktioniert auch soweit gut..nur kommt mir das mit dieser "while (i)" Schleife etwas unschön vor..kann man das besser machen?
Und könntest du mir vielleicht (numeric_limits<int>::max(),'\n') ein bischen erläutern was das genau macht? Wäre supermfg moonbeam
-
std::cin.ignore()
http://www.cplusplus.com/reference/iostream/istream/ignore/istream& ignore ( streamsize n = 1, int delim = EOF );
n
Maximum number of characters to extract (and ignore).
This is an integer value of type streamsize.So, da wir den Eingabestream von Cin leeren müssen und wir eine Integer Zahl einlesen wollen, geben wir die Maximale Zahl von Integer über.
std::numeric_limits<>::max()
http://www.cplusplus.com/reference/std/limits/numeric_limits/static T max() throw();
max() T Maximum finite value.
Equivalent to CHAR_MAX, SCHAR_MAX, UCHAR_MAX, SHRT_MAX, USHRT_MAX, INT_MAX, UINT_MAX, LONG_MAX, ULONG_MAX, FLT_MAX, DBL_MAX or LDBL_MAX, depending on type.i=1 ... i = false
... Das ist hässlich. Entweder Integer oder Boolean.
//damit ich z.B. auch 15min eingeben kann
dein std::cin nimmt bei einer Eingabe die jetzt z.B. "15min" entspricht, die 15 an, aber bei dem nächsten cin das ausgeführt wird, wird da "min" reingeklatscht. Wenn du das willst, naja...
Ich sehe dich die Variable i auf false setzen, aber nicht auf true. Wie kommst du aus dieser Schleife wieder raus ?
Du hast nur ein paar Schönheitsfehler, ansonsten kann man das schon lassen.
-
dein std::cin nimmt bei einer Eingabe die jetzt z.B. "15min" entspricht, die 15 an, aber bei dem nächsten cin das ausgeführt wird, wird da "min" reingeklatscht. Wenn du das willst, naja...
Ich sehe dich die Variable i auf false setzen, aber nicht auf true. Wie kommst du aus dieser Schleife wieder raus ?
Du hast nur ein paar Schönheitsfehler, ansonsten kann man das schon lassen.hm aber das hab ich doch grade eingefügt damit er die "min" wieder rauslöscht.
Nun will ich eine weitere Fehlermeldung einfügen für den Fall, das meine Variable nicht im Toleranzbereich liegt.
Nur hab ich das mit diesem "throw int()" und "catch(const int )" nicht wirklich verstanden..hab ich nur aus einem Beispiel. Wenn ich das nun Versuche dann müsste ich ja da irgendwas anderes reinschreiben damit er das unterscheiden kann. funktioniert nur leider nicht. So siehts bisher aus . Kannst du mir da vieleicht auch noch helfen?int i=true; cout<< "Flughafensimulation"<<endl; cout<<"Simulationsparameter: "<<endl; cout<<"Tolleranzzeit fuer ankommende Flugzeuge( 1 - 60 )min: "; while (i) { try { if(!(cin>>time_rndarrive )){ //abfangen von nicht zahlen throw int(); } else { i=false; cin.clear(); //damit ich auch zb. 15min eingeben kann cin.ignore(numeric_limits<int>::max(),'\n'); } if (time_rndarrive<1 || time_rndarrive>60) { //abfangen zahlen nicht im toleranzbereich throw ???; } else { i=false; cin.clear(); cin.ignore(numeric_limits<int>::max(),'\n'); } catch(const int ) { cout << "Fehler! Eingegebener Wert war keine Zahl! Bitte nochmal eingeben: "; cin.clear(); cin.ignore(numeric_limits<int>::max(),'\n'); } catch(??? ) { cout << "Fehler! Eingegebener Wert lag nicht im Toleranzbereich! Bitte nochmal eingeben: "; cin.clear(); cin.ignore(numeric_limits<int>::max(),'\n'); } }
-
WAS funktioniert nicht ? Wenn du willst das ich das hier alles on my own mache, dann gib mir den ganzen Code.
Edit:
int i = true;
Kannst du mir sagen was das soll?
Wofür gibt es denn bool ? Der wurde nicht nur aus Langeweile gemacht, oder bool wurde noch hinzugefügt, weil einer keine Lust auf eine gerade Zahl an Datentypen hatte.
Außerdem fehlt eine Klammer in Zeile 27.
-
sry..ich bin ziemlich Programmieranfänger
dachte true wäre 1 und false 0 und dass man das so vl besser versteht.
Ich hab mich nun doch entschieden nur eine standard Fehlermeldung zu machen und hab das ganze noch in eine Funktion gepackt die dann meinen Wert zurückgibt. Funktioniert auch jetzt wunderbar soweit ich das ausprobiert habFällt dir vl noch irgendwas auf was schlecht ist? Vielen Dank auf jeden Fall schonmal..war echt ne super Hilfe
int cin_exception(int min,int max) { int i = 1; int parameter; while (i) { try { if (!(cin >> parameter) || (parameter < min || parameter > max)) { //Abfangen von nicht Zahlen throw("error"); } else { i = 0; cin.clear(); cin.ignore(numeric_limits<int>::max(), '\n'); } } catch (const char* error) { cout << "ERROR! Fehlerhafte Eingabe. Bitte nochmal eingeben: "; cin.clear(); cin.ignore(numeric_limits<int>::max(), '\n'); } } return parameter;
-
dachte true wäre 1 und false 0 und dass man das so vl besser versteht.
In C++ ist
false
0 und alles anderetrue
. In dem Fall sind aber die Schlüsselwörter sicher sinnvoller..
-
Mach doch bitte noch aus dem int i = 1 ein bool i = true und in der else Verzweigung i = false.
-
Ich wüsste nicht, wieso man hier exceptions braucht... Die falsche Schleife wurde auch gewählt usw... ^^
Ich würds so implementieren:void clear_stream(std::istream &stream) { stream.clear(); stream.ignore(std::numeric_limits<int>::max(), '\n'); } int cin_get(int min, int max) { int ReturnValue; bool again = true; do { if (!(std::cin >> ReturnValue) || (ReturnValue < min || ReturnValue > max)) std::cout << "ERROR! Fehlerhafte Eingabe. Bitte nochmal eingeben: "; else again = false; clear_stream(std::cin); } while(again); return ReturnValue; }
Dann hab ich keine sinnlose Code-Duplikation und übersichtlicher ist es imho auch noch...
bb
-
unskilled schrieb:
...
Ich weiss auch nicht wofür er Exceptions braucht. Hab ihm auch eine normale While-Schleife gegeben, aber sein Lehrer mags wohl lieber umständlich.
@unskilled
So ist es auch net schlecht, aber man könnte aus der do-while noch eine kürze while-Schleife machen und ich weiss auch net was gegen mein Beispiel spricht :p#include <iostream> int my_cin(int first_value, int second_value) { int user_input; while(!(std::cin >> user_input) || user_input < first_value || user_input > second_value) { std::cout << "Falsche Eingabe! Die Eingabe ist keine Zahl oder liegt nicht im Bereich!" << std::endl; std::cin.clear(); std::cin.ignore(std::numeric_limits<int>::max(), '\n'); } return user_input; } int main() { std::cout << my_cin(1, 60); }
Das
std::cin.clear(); std::cin.ignore(std::numeric_limits<int>::max(), '\n');
kann man natürlich noch in eine Funktion packen, wenn man sie denn überhaupt öfters brauch.
-
ich weiss auch net was gegen mein Beispiel spricht
Bei deiner Funktion wäre der Stream nach einer Eingabe nicht 100%ig leer
Also wenn ich 15m oder 15 2 oder so eingebe, steht dann noch "m" bzw "2" im Stream - das wollte der TO offensichtlich nicht, deshalb ist das bei mir auch nicht so ^^
ansonsten könnte man sich drum streiten, welche fkt schöner ist ^^bb
edit:
so find ichs übrigens am schönsten - allerdings wäre das wohl ein wenig zu kompliziert für den TO ^^void clear_stream(std::istream &stream) { stream.clear(); stream.ignore( stream.rdbuf()->in_avail(), '\n' ); } template <typename T> T get(std::istream &in, std::ostream &out) { T ReturnValue; while (!(in >> ReturnValue)) { out << "Wrong input format - please try again:"; clear_stream(in); }; clear_stream(in); return ReturnValue; } template <typename T> T get(std::istream &in, std::ostream &out, const T &lower_bound, const T &upper_bound) { T ReturnValue = get(in, out); while( (ReturnValue < lower_bound) || (ReturnValue > upper_bound) ) { out << "Input out of bounds - please try again:"; clear_stream(in); ReturnValue = get(in, out); }; return ReturnValue; }
bb