(gelöst) Benutzereingabe "1" OK "1 a" nichtOK!
-
b1419589 schrieb:
[...] (Dass die Eingabe von "Leerzeichen" + 1 immer noch als 1 akzeptiert wird, spielt keine Rolle.) [...]
Gefixt. Hatte im Original fälschlicherweise
std::skipwsstatt richtigstd::noskipws.
-
@Swordfish, dankeschön! Alles perfekt! Damit wurden alle meine Probleme gelöst und Fragen beantwortet.
-
#include <cctype> // std::isspace() #include <limits> // std::numeric_limits<>::max() #include <iomanip> // std::noskipws() #include <iostream> bool only_whitespace(std::istream & is) // true, wenn nur white-space Zeichen in is sind. { std::istream::int_type ch = 0; // solange das naechste Zeichen in is while (ch != '\n' && ch != EOF // kein Newline ist und auch das Streamende nicht erreicht ist && std::isspace(ch = is.peek()) // und ein Leerzeichen, Tab, ... ist (peek() nur ansehen, nicht extrahieren) ) { is.get(); // extrahiere das Zeichen aus is (= werfe das angesehene Zeichen weg). } return ch == '\n' || ch == EOF; // ist die while()-Schleife wegen '\n' oder EOF abgebrochen? // wenn nicht, war es ein anderes Zeichen das nicht isspace() ist. } int main() { int choice; for (choice = 0; std::cout << "Input: " && !(std::cin >> std::noskipws >> choice) || !only_whitespace(std::cin) || (choice < 1 || 4 < choice);choice++) { std::cerr << "Input error!\n\n"; // eine Fehlermeldung ausgeben std::cin.clear(); // Fehlerflags loeschen, falls der Extraktionsversuch fehlgeschlagen ist std::cin.ignore( // weitere Zeichen in cin ignorieren std::numeric_limits< std::streamsize >::max(), // Anzahl zu ignorierender Zeichen, vorsichtshalber die groesztmoegliche Anzahl annehmen '\n' // solange kein '\n' daherkommt ); } std::cout << choice << "\n\n"; // getroffene Auswahl ausgeben }
-
und? was bringt die Nachplapperei?
-
Die for-Schleife ist nicht richtig!!!
-
Wie wärs mit
std::string str; std::getline(std::cin, str); int choice = boost::lexical_cast<int>(str); // Wirft Exception wenn str nicht nach int konvertiert werden kann?
-
Es gibt an der for-Schleife nichts auszusetzen. Sie macht genau das, was Swordfish mit einer do-while-Schleife auch macht!
-
hustbaer schrieb:
Wie wärs mit
std::string str; std::getline(std::cin, str); int choice = boost::lexical_cast<int>(str); // Wirft Exception wenn str nicht nach int konvertiert werden kann?
Danke hustbaer, aber boost ist für mich jetzt nochmal eine neue Bibliothek. So lerne ich die Grundlagen nicht, wenn ich ständig auf eine Bibliothek ausweiche.
Mit Boost Lexical_cast ist die Konvertierung von string to z.B. int sicherlich einfacher oder besser. Danke für deine Antwort.
-
MarkusMundM schrieb:
#include <cctype> // std::isspace() #include <limits> // std::numeric_limits<>::max() #include <iomanip> // std::noskipws() #include <iostream> bool only_whitespace(std::istream & is) // true, wenn nur white-space Zeichen in is sind. { std::istream::int_type ch = 0; // solange das naechste Zeichen in is while (ch != '\n' && ch != EOF // kein Newline ist und auch das Streamende nicht erreicht ist && std::isspace(ch = is.peek()) // und ein Leerzeichen, Tab, ... ist (peek() nur ansehen, nicht extrahieren) ) { is.get(); // extrahiere das Zeichen aus is (= werfe das angesehene Zeichen weg). } return ch == '\n' || ch == EOF; // ist die while()-Schleife wegen '\n' oder EOF abgebrochen? // wenn nicht, war es ein anderes Zeichen das nicht isspace() ist. } int main() { int choice; for (choice = 0; std::cout << "Input: " && !(std::cin >> std::noskipws >> choice) || !only_whitespace(std::cin) || (choice < 1 || 4 < choice);choice++) { std::cerr << "Input error!\n\n"; // eine Fehlermeldung ausgeben std::cin.clear(); // Fehlerflags loeschen, falls der Extraktionsversuch fehlgeschlagen ist std::cin.ignore( // weitere Zeichen in cin ignorieren std::numeric_limits< std::streamsize >::max(), // Anzahl zu ignorierender Zeichen, vorsichtshalber die groesztmoegliche Anzahl annehmen '\n' // solange kein '\n' daherkommt ); } std::cout << choice << "\n\n"; // getroffene Auswahl ausgeben }@MarkusMundM, nein diese Schleife macht nicht dasselbe, was Swordfish bereits mit einer do-while Schleife gelöst hat.
-
OK.
Aber du kannst ja mal reingucken wie Boost es macht
IIRC verwenden die nen (etwas modifizierten und auf etwas bessere Geschwindigkeit modifizierten) Stringstream.
Da wird dann erstmal der Ausgangswert "reingeschiftet" (stream insertion, "<<" halt).
Und dann wird versucht das "rauszushiften" (stream extraction, ">>") was man haben möchte.Und dann wird geprüft
a) Ob der Stream danach noch "good" ist und
b) Ob der Stream danach leer istWenn beides zutrifft war die Konvertierung erfolgreich.
Finde ich weitaus eleganter als direkt in cin zu gucken ob auch wirklich ein Newline das nächste Zeichen ist.