Fehler bei switch Anweisung
-
komisch schrieb:
cin >> number_1; // hinter dieser Zeile in deinem Code das hier einfügen: cin.ignore( std::numeric_limits< std::streamsize >::max(), '\n' );ich versuchs einfach mal zu erklären:
mit Zeile 1 liest du wie gewohnt etwas von der Standardausgabe ein.
Was passiert aber im Fehlerfall (Als Programmierer lässt du ein int eingeben, der User gibt aber z.B. "123abc456" ein.)
Der Inputstream hat intern diese Zeichen alle (ob als String oder als sonstwas ist implementierungsabhängig) vorhanden. Er guckt dann zeichenweise, ob das Zeichen zur Anforderung (also zu einem int) passt. In dem konkreten Fall liest er die 1, 2 und die 3 und schiebt sie auch direkt aus dem Puffer (also dem Speicher-String). Dann merkt er "Oh, das a passt aber nicht".Intern hat der Stream dann noch ein Flag (z.B. eine bool'sche Variable) für den Fehlerfall, die er sogleich auf Fehler setzt und er bricht mit dem Lesen ab.
Jetzt ist dein Standard-Input-Stream erstmal fertig, bzw ausser Gefecht. Diesen Status muss man aber abfragen, denn von sich aus meldet der Stream nichts.
Szenario 1: Du nutzt cin(also deinen Stream) einfach weiter wie gewohnt und liest jetzt noch einen int ein (bzw willst). Intern sieht der Stream aber jetzt "Oh, da steht noch was im Puffer, ich nehm das zuerst. Aber huch, da ist ja auch ein Fehler. Da hab ich keine Lust mehr und streike". Das Ergebnis für deine zweite Eingabeauforderung: Der User wird gar nicht erst gefragt(der Stream gibt ja schon vorhergeschriebenen Inhalt vor), aber hat die int Variable beschrieben.
Auf gut deutsch: inputstreams in einer Schleife fragen den User bis zur Falscheingabe und laufen danach naja ungefragt im Endlosmodus weiter.Szenario 2: Du fragst nach jeder Eingabe den Stream, ob er noch ganz beisammen ist, etwa so:
int i; if ( !(cin >> i) ) { } // oder so cin >> i; if ( !cin ) { } // oder so cin >> i; if ( cin.good() ) { } // oder so cin >> i; if ( cin.fail() ) { }Und im Fehlerfall korrigierst du den/die Fehler.
Und das macht man mit Ignore. Dieses löscht nämlich beliebig viele Zeichen (erster Parameter) aus dem Stream. Die andere Möglichkeit ist, es löscht so viele Zeichen im Streambuffer bis ein gewisses Zeichen kommt (der zweite Parameter). Der Fall von den beiden geschilderten, der zuerst eintritt, entscheidet.
In dem von komisch genannten Beispiel ist das erste Argument die grösste Zahl die eine Streamgrösse annehmen kann. (std::numeric_limits< std::streamsize >::max())Danach ist der Streambuffer leer. Das Failbit ist aber noch gesetzt, dieses entfernt man mit clear().
Ist eigentlich ganz einfach und logisch. Aber frag nicht warum der Standard das so will und nicht die Streams automatisch korrigiert, dafür gibt es viele Gründe (sowohl dafür als auch dagegen).
int i; cin >> i; if ( !cin ) { cin.ignore(std::numeric_limits< std::streamsize >::max(), '\n'); cin.clear(); }