Eingaben lesen
-
So in der Richtung....

Geht aber leider immer noch nicht so:
#include <iostream> #include <sstream> #include <fstream> #include <stdexcept> using namespace std; int main(void) { int ival; while(cin >> ival, !cin.eof()) { if(cin.fail()) { cerr << "BAD DATA"; cin.clear(istream::failbit); cin.ignore(); continue; } } }
-
777 schrieb:
Geht aber leider immer noch nicht so:
#include <iostream> #include <sstream> #include <fstream> #include <stdexcept> using namespace std; int main(void) { int ival; while(cin >> ival, !cin.eof()) { if(cin.fail()) { cerr << "BAD DATA"; cin.clear(istream::failbit); cin.ignore(); continue; } } }Hmm, sollte aber eigentlich passen.
Wobei, ignore() ohne weitere Parameter verwirft genau ein Zeichen der Eingabe - d.h. wenn du viel Müll eingegeben hast, bekommst du entsprechend viele "BAD DATA" Meldungen. Versuch' mal, einen etwas größeren Abschnitt zu verwerfen:
cin.ignore(numeric_limits<size_t>::max(),'\n');(braucht noch ein '#include <limits>).
-
#include <iostream> // std::cin, std::cerr, std::cout #include <limits> // std::numeric_limits int main(void) { int ival(0); while (!(std::cin >> ival)) { std::cerr << "[invalid data]" << std::endl; std::cin.clear(); std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n'); } std::cout << "\"ival\" = " << ival << ";" << std::endl; }... so geht das ^^ Guck dir mal den operator! von std::istream an ... evtl. dann noch mal gucken was bei std::istream::clear und was bei std::istream::ignore genau passiert

-
Hey,
Also der folgende Code ergibt bei mir das selbe:
#include <iostream> #include <sstream> #include <fstream> #include <stdexcept> #include <limits> using namespace std; int main(void) { int ival; while(cin >> ival, !cin.eof()) { if(cin.fail()) { cerr << "BAD DATA"; cin.clear(istream::failbit); cin.ignore(numeric_limits<size_t>::max(),'\n'); continue; } } }(D)Evils Code funktioniert zwar, aber er ist einfach ein ganz anderer Weg zur Lösung.
Ich würde aber am liebsten den Weg zur Lösung verstehen, der im Buch gesagt wird.*
Ich hab als Compiler DEV C++... vielleicht liegts ja dadran
cya
David*Also so mit Failbits und Statusflags das Lösen.
-
Hallo,
du verwendest die Methode clear falsch. clear löscht a) alle Fehlerbits und b) setzt das Fehler-bit, das an die Methode übergeben wird. Der Default-Wert ist basic_ios::goodbit, du übergibst aber failbit. D.h. nach dem Aufruf von clear ist wieder das failbit gesetzt; nicht das was du eigentlich willst.Weiterhin: ignore erwartet einen Wert vom Typ streamsize. streamsize ist ein *signed* Integertype. Du übergibst aber numeric_limits<size_t>::max(), wobei size_t ein *unsigned* Integertype ist. D.h. bei der Umwandlung kann -1 herauskommen und wenn deine Implementation z.B. das Argument auf > 0 vergleicht, passiert hier gar nix.
Korrekt wäre:
a) clear()
b) Verwendung von std::numeric_limitsstd::streamsize::max()#include <iostream> #include <sstream> #include <fstream> #include <stdexcept> #include <limits> using namespace std; int main(void) { int ival; while(cin >> ival, !cin.eof()) { if(cin.fail()) { cerr << "BAD DATA"; cin.clear(); cin.ignore(numeric_limits<std::streamsize>::max(),'\n'); continue; } } }So wird ein Schuh draus.
-
WOW!
Endlich ein Quelltext, welcher Funktioniert.
Super!!!Aber noch eine Frage:
EOF heißt meines Wissens 'End Of File'.
Was genau hat dieser Header der schleife für einen Sinn?
Wann wird das EOF-Bit im Stream gesetzt?cya
David
-
Ja, EOF ist das Dateiende - das wird gesetzt, wenn die Datei zu Ende ist (wie der Name schon andeutet). Für cin löst du einen EOF aus, indem du Ctrl+Z oder Ctrl+D drückst (hängt vom System ab).
-
Ahh!!!
Dein letzter Satz hat meine Frage schon beantwortet... habe das mal ausprobiert und wenn ich in meinem Schleifenprogramm Strg+Z drücke wirds tatsächlich beendet!!!
THX
cya
David
-
Kleine Ergänzung: Vielleicht solltest du eine andere Kennung für "das war der letzte Wert" verwenden als ein EOF. Wenn der User die Eingaben mit Strg+Z abbricht, ist cin nämlich anschließend "tot" (und ich bin mir auch nicht sicher, ob du die Konsole aus dem Programm heraus reaktivieren kannst) und du kannst keine Eingaben mehr entgegennehmen.
Ich würde es eher so lösen:
while(true)//wird später per break verlassen { cin >> ival if(cin.fail()) { cerr << "BAD DATA"; cin.clear(); char test = cin.get() if(test=='q') break; cin.ignore(numeric_limits<std::streamsize>::max(),'\n'); continue; } }
-
Wenn ich auch mal was sagen darf: EDV

Gruß Tobi.
-
CStoll schrieb:
Wenn der User die Eingaben mit Strg+Z abbricht, ist cin nämlich anschließend "tot" (und ich bin mir auch nicht sicher, ob du die Konsole aus dem Programm heraus reaktivieren kannst)
Doch, man kann den Toten wieder zum Leben erwecken:
#include<iostream> struct StreamDefi{ void brizzl(std::ios& io, int voltage) { io.clear(); ++voltage; //supress warnings about unused variables } } using std::cin; using std::cout; int main() { for (char c; cin; cin.get(c)) cout << c; if (cin.eof()) { StreamDefi Defibrilator; Defibrilator.brizzl(cin, 240); //BRZZL cin lebt wieder! } }*scnr*
-
Wie gesagt, ich war mir nicht sicher. Aber clear() setzt afaik nur die Statusflags von cin zurück - ob das ausreicht, um die dahinterliegende Konsole wieder zu reaktivieren, ist die andere Frage.
(btw, was soll das '++voltage' bringen?)