Verhalten bei bei Schleifenverarbeitung
-
Hallo,
zu Übungszwecken habe ich etwas mit den verschiedenen Schleifenarten herumgespielt. Dabei kam z.B. folgender Code heraus:
(Zur Übersicht für mich sind ein paar extra Leerzeilen mit drin)
#include <iostream> #include <cstdlib> using namespace std; int main () { bool durchlauf; int ergebnis = 1; do { int multiplikator; cout << "x = " << ergebnis << '\n'; cout << "Geben Sie einen Multiplikator > 0 ein.\n"; if (!(cin >> multiplikator)) { cout << "Eingabefehler - keine Zahl\n"; exit(1); } else if (!multiplikator) { durchlauf = false; } else { ergebnis*=multiplikator; durchlauf = true; } } while (durchlauf); return 0; }Die Ausführung läuft soweit korrekt, bis auf eine Ausnahme. Wenn ich als Multiplikator eine Gleitkommazahl eingebe, z.B. 4.1, dann wird die Berechnung mit 4 als Multiplikator ausgeführt, was soweit ja auch korrekt ist, allerdings lauft das Programm dann weiter und in die erste Schleife hinein.
Ich verstehe nicht ganz, wieso das so ist. Wenn ich eine Gleitkommazahl einem int zuweise, dann sollte doch eigentlich alles nach dem Komma (und inklusive des Kommas) ignoriert werden, zumindest nach den Erklärungen, die ich bisher gelesen habe.
Kann mir dazu jemand einen Tip geben?
-
Capet schrieb:
Ich verstehe nicht ganz, wieso das so ist. Wenn ich eine Gleitkommazahl einem int zuweise, dann sollte doch eigentlich alles nach dem Komma (und inklusive des Kommas) ignoriert werden, zumindest nach den Erklärungen, die ich bisher gelesen habe.
Das stimmt ja auch, aber du weist hier nirgendwo eine Gleitkommazahl einem int zu. Du liest ein int ein und dabei wird nur solange gelesen, wie keine Zeichen vorkommen, die in einem int nichts verloren haben. '.' ist so eins.
Beim nächsten Durchlauf ist bei Eingabe von 4.1 also noch ".1" im Eingabepuffer. '.' ist immer noch kein erlaubtes Zeichen und daher bricht das Ganze ab.
if-Schleifen gibt es übrigens nicht.
-
Das von Athar erzählte lässt sich hiermit
int test; cin >> test; cout << test << endl; cout << cin.rdbuf() << endl;zeigen. Da siehst du, was im Buffer hängen bleibt.
-
Ok, danke für den Hinweis.
Das heißt, man könnte das umgehen, in dem man nach der Berechnung im else-Abschnitt den Puffer leeren würde.
-
man könnte es beheben indem man eine ganze zeile mittels getline() einliest, und diese dann selbst in einen integer wandelt.
-
hustbaer schrieb:
man könnte es beheben indem man eine ganze zeile mittels getline() einliest, und diese dann selbst in einen integer wandelt.
Neeiiiin - getline ist doof
Besser. (cin >> test).ignore( 999, '\n);
-
Mal abgesehen, dass das der Lesbarkeit halber besser in zwei Zeilen geschrieben gehört, macht das nicht, was du willst, wenn dir jemand "abc" in einen Integer zu schreiben versucht.
Zwar kann man sich da mit clear und ignore was zusammenschustern, aber wenn dein Input zeilenweise gedacht ist, macht es auch Sinn, ihn zeilenweise zu verarbeiten - insofern hat hustbärs Ansatz durchaus etwas für sich.