(gelöst) Benutzereingabe "1" OK "1 a" nichtOK!
-
b1419589 schrieb:
Ich danke euch vielmals für eure Hilfe.
@Swordfish, deine Lösung macht genau das, was ich haben möchte, (Dass die Eingabe von "Leerzeichen" + 1 immer noch als 1 akzeptiert wird, spielt keine Rolle.)
nämlich eine Funktion, mit der eine Benutzereingabe nur von 1,2,3 oder 4 in einer Schleife akzeptiert wird und mit der Eingabe von 4 das Programm beendet wird.
Perfekt! Aber ich verstehe es nicht! Ein paar Kommentare wären für mich als Anfänger sehr hilfreich, womit ich in aller Bescheidenheit keine falsche Erwartung zeigen möchte.@MfG,deine Lösung ist für mich als Anfänger verständlich und so aufgebaut, dass ich jeden Schritt nachvollziehen kann. Ich hätte noch erwähnen sollen, was die Funktion machen soll.
Dass die Eingabe von nur 1, 2, 3 oder 4 möglich sein soll, hast du prima gelöst. Darüber hinaus möchte ich, dass mit der Eingabe von 4 das Programm beendet wird, bei den Zahlen 1,2,3 aber die Schleife durchläuft und andere Aufgaben erfüllt werden.@asfdlol, vielen Dank für deine Unterstützung!
@oenone & MarkusM&M, ich versuche immer eine for schleife zu verwenden, da ich sie übersichtlicher finde, als while oder do-while.
Schöne Grüße
ok dann hat es wenigstens sinn gemacht...

freut mich das du dein problem lösen konntest...ich wollte dir mit meinem beispiel genau auf einfache und verständliche weise das nahe bringen...

freut mich wenn du es verstanden hast und nachvollziehen konntest...
das war ja das worum es ging, aber es kann an meinem code noch viel/bzw. das was du genau benötigst optimiert werden... (wie meine vorredner schon erwähnt haebn)
-
b1419589 schrieb:
Ich danke euch vielmals für eure Hilfe.
@Swordfish, deine Lösung macht genau das, was ich haben möchte, (Dass die Eingabe von "Leerzeichen" + 1 immer noch als 1 akzeptiert wird, spielt keine Rolle.)
nämlich eine Funktion, mit der eine Benutzereingabe nur von 1,2,3 oder 4 in einer Schleife akzeptiert wird und mit der Eingabe von 4 das Programm beendet wird.
Perfekt! Aber ich verstehe es nicht! Ein paar Kommentare wären für mich als Anfänger sehr hilfreich, womit ich in aller Bescheidenheit keine falsche Erwartung zeigen möchte.#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; do { // solange while( std::cout << "Input: ", !( std::cin >> std::noskipws >> choice ) // der Extraktionsversuch eines Integers aus cin fehlschlaegt || !only_whitespace( std::cin ) // oder nach dem Extraktionsversuch noch weitere Zeichen auszer white-space in cin stehen || ( choice < 1 || 4 < choice ) // oder das gelesene choice nicht in 1...4 liegt ) { 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 } while( choice != 4 ); }
-
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.