cin seltsames Verhalten in while-Schleife mit Plausibilitätsprüfung
-
Shinja schrieb:
Jetzt muss ich mich doch mal selbst zitieren: warum ist diese (für mich pers. einfacherer Variante) nicht praktikabel? (Frage zum eigenen Verständnis)
frag ich mich auch :p.
wahrscheinlich ist es einfach schöner, zuerst ne endlosschleife zu programmieren und dann mit break rauszuspringen, anstatt ne anständige abbruchbedingung zu nutzen
.Vielleicht will man auch unbedingt nen c++ stream mit c mitteln clearen, um damit je nach standardbibliothek fast unmöglich zu findende fehler zu produzieren ;).
Vielleicht liegts auch einfach an dem Syntaxfehler. Hinter do kommen keine "()".
so funktionierts bei mir perfekt:
double d=0.0; do { cout<<"Bitte geben sie eine Zahl >10 ein: "; while(!(cin>>d)) { cin.clear(); cin.ignore(numeric_limits<streamsize>::max(),'\n'); cout<<"\nFehlerhafte eingabe! Bitte geben sie eine Zahl >10 ein: "; } } while(d<10.0); cout<<"eingabe:"<<d;
-
double d=0.0; do { cout<<"Bitte geben sie eine Zahl >10 ein: "; while(!(cin>>d)) { cin.clear(); cin.ignore(numeric_limits<streamsize>::max(),'\n'); cout<<"\nFehlerhafte eingabe! Bitte geben sie eine Zahl >10 ein: "; } } while(d<10.0); cout<<"eingabe:"<<d;Mit welchen Header-Dateien?
Nicht jeder ist ein solcher Crack wie du!
schreib doch mal nen vollständigen code
max() ist unbekannt...
wenn ihr einfach nen vollständigen code schreiben würdet, könnten sich die nicht-profis auch mitunterhalten
-
#include<limits>
-
Shinja schrieb:
...
Jetzt muss ich mich doch mal selbst zitieren: warum ist diese (für mich pers. einfacherer Variante) nicht praktikabel? (Frage zum eigenen Verständnis)
...- Weil sie fehlerhaft ist und sich nicht kompilieren lässt.
- Als C++ Einsteiger weiß man nicht, das man für:
cin.ignore(numeric_limits<streamsize>::max(),'\n');
eine extra Headerdatei einbinden muss.
Daher nimmt man einfach die Lösung, wo man die Fehler zunächst intuitiv schneller beseitigen kann, oder am besten erst gar keine vorhanden sind.
Wenn man nun die von otze verbesserte Version dahernimmt und <limits> mit einbindet, funktioniert das in der Tat einwandfrei.
Darum gefällt mir persönlich diese Version auch am besten, weil sie im Gegensatz zu meiner ohne die Fehlerprüfung über strtod auskommt.
Gruß, p.
-
Matop schrieb:
Mit welchen Header-Dateien?
Nicht jeder ist ein solcher Crack wie du!
schreib doch mal nen vollständigen code
max() ist unbekannt...
wenn ihr einfach nen vollständigen code schreiben würdet, könnten sich die nicht-profis auch mitunterhaltengoogle ist dein Freund :D. erster treffer numeric_limits: http://www.cpp-tutor.de/cpp/le13/le13_03.htm. Und schon kannst du wieder mitreden.
Du kannst immer davon ausgehen, dass alles was hier gesagt wird,standard c++ ist(ausser, es wird ausdrücklich gesagt, dass man fremdcode wie boost nutzt). Dann reicht googlen nach dem unbekannten wort,zb "c++ numeric_limits", und man weis wieder worum es geht(wenn man nicht weis, was ein code macht ist es eh nicht sinnvoll ihn einfach zu kopieren. Das ist viel zu fehleranfällig und man ist aufgeschmissen, wenn man was ändern will, also muss man im zweifelsfall eh googlen
)header wurde ja jetzt genannt, läuft mit iostream und limits
-
Stellt sich mir gerade die Frage, ob man auf die Zeile:
cin.ignore(numeric_limits<streamsize>::max(),'\n');
ganz verzichten kann.Ich denke mal, die obige Zeile kann man rausschmeissen.
Dann müsste man noch prüfen, ob korrekt konvertiert wurde.
Grund:
Wenn zu viele Zeichen eingegeben werden, dann wird die while-Schleife beendet und in der Variable d steht #inf.Ich darf an dieser Stelle in aller Bescheidenheit darauf hinweisen, das diese Gegebenheit bei meiner Version abgefangen wird!

-
proggingmania schrieb:
Grund:
Wenn zu viele Zeichen eingegeben werden, dann wird die while-Schleife beendet und in der Variable d steht #inf.Eigentlich wird die Whileschleife gerade erst dann beendet, wenn die Eingabe vollständig korrekt war (also wenn das erste ungültige Zeichen nach der Zahl ein Whitespace ist). Und ich glaube auch sehr stark, dass nicht definiert ist was in so einem Fall in d steht (oder d unverändert bleibt).
EDIT:
Ich lese gerade unter mir, dass mit "zu viele Zeichen" auch eine zu lange Zahl gemeint sein könnte. Ich ging aus irgendeinem Grund von ungültigen Zeichen aus.
-
proggingmania schrieb:
Stellt sich mir gerade die Frage, ob man auf die Zeile:
cin.ignore(numeric_limits<streamsize>::max(),'\n');
ganz verzichten kann.Ich denke mal, die obige Zeile kann man rausschmeissen.
nein kann man nicht. die fehlerhaften zeichen werden nicht automatisch aus dem buffer entfernt(man könnte ja nochmal etwas damit machen wollen), und beim nächsten aufruf von op>> versucht der stream wieder, dieses zeichen einzulesen, usw.
Dann müsste man noch prüfen, ob korrekt konvertiert wurde.
Grund:
Wenn zu viele Zeichen eingegeben werden, dann wird die while-Schleife beendet und in der Variable d steht #inf.Ich darf an dieser Stelle in aller Bescheidenheit darauf hinweisen, das diese Gegebenheit bei meiner Version abgefangen wird!

ich glaube nicht, das jemand hier soviele zeichen vor hat einzugeben. double hält schon ne menge aus

-
otze schrieb:
nein kann man nicht. die fehlerhaften zeichen werden nicht automatisch aus dem buffer entfernt(man könnte ja nochmal etwas damit machen wollen), und beim nächsten aufruf von op>> versucht der stream wieder, dieses zeichen einzulesen, usw.
Ooopsie, hattu recht, dann gibts ne Endlosschleife, wenn man nen Buchstaben
eintippt.LordJaxom schrieb:
Eigentlich wird die Whileschleife gerade erst dann beendet, wenn die Eingabe vollständig korrekt war (also wenn das erste ungültige Zeichen nach der Zahl ein Whitespace ist). Und ich glaube auch sehr stark, dass nicht definiert ist was in so einem Fall in d steht (oder d unverändert bleibt).
Ein Grund mehr, sich den Inhalt von d anzugucken. Bei mir steht nach einer Eingabe von zu vielen Zeichen das besagte #inf.
Korrekt: 1.#inf
Das soll wohl soviel wie infinite, also Undendlich bedeuten.
Klar, infinite ist größer als 10, somit wird die Schleife vermeintlich korrekt beendet.
-
Dazu hab ich noch ein schnuckeliges Funktiönchen gefunden:
int _finite( double x );
Deklariert in:
float.hDamit liessen sich zu große Zahlen abfangen.
-
@proggingmania das sieht mir aber nicht sonderlich standardkonform aus, zumindest sagt mir das der "_" am anfang.
dafür kann man aber auch numeric_limits verwenden:
double d; ... if(d==numeric_limits<double>::infinity()) { cout<<"zahl zu groß"; }
-
Sorry für den Syntaxfehler, hatte erst das while an den Anfang geschrieben und dann gelöscht, ka wieso ich die Klammern stehen gelassen habe...
Es braucht neben limits auch ein iostream und ein using namespace std; damit es funktioniert. limits hätte ich erwähnen sollen.