[Gelöst] Verhindern, dass int als char gelesen werden kann. (123 -> '1')
-
Hallo,
angenommen ich will etwas einlesen mit dem Format
n-n-n-x, n seien Integer und x ein Char,
wie kann ich verhindern, dass folgende Art von Input trotzdem durchgeht, obwohl es eigentlich falsch ist:
1234-5678-101-111 // ergibt natürlich 1234-5678-101-1Jedoch ist das eigentlich nicht das, was man will, oder? Ich meine, einfach aus 111 eine 1 machen scheint mir eben nicht so toll.
Mein Code zum Einlesen:
// ISBN // nicht unbedingt das echte Format, aber ist erstmal egal // ... int n1, n2, n3; char x; // ... std::istream& operator>>(std::istream& is, ISBN& isbn) { char ch1, ch2, ch3; is >> isbn.n1 >> ch1 >> isbn.n2 >> ch2 >> isbn.n3 >> ch3 >> isbn.x; if (!is) return is; if (ch1 != '-' || ch2 != '-' || ch3 != '-') { is.clear(std::ios_base::failbit); return is; } return is; }Ich weiß also nicht, wie ich überprüfen kann, dass der letzte Teil tatsächlich nur ein char ist, denn wenn ich aus '111' einen char lese, funktioniert das ja einwandfrei (ist ja auch ok so) --> '1', aber eben nicht das, was in diesem Fall gewollt ist. Ich brauche also Hilfe bei den nötigen Anpassungen meines input Operators, damit solche Eingaben, wie oben beschrieben, ebenfalls "nicht durchgehen"
Hoffe das ist so verständlich, und jemand kann mir da ein paar Tips geben.
LG
-
Prüf doch einfach, ob das Ergebnis von peek() nach der Einleseoperation ein Whitespace ist.
-
Du liest die gesamte Zeile, dann validierst du sie.
-
Die Methode mit peek() funktioniert, wenn ich direkt aus dem istream lese, da ist der Zeilenumbruch wohl noch drin.
Wenn ich dasselbe mit einem istringstream mache, der mithilfe von getline gefüllt wird, dann ist das '\n' scheinbar nicht mit dabei. ('\n' ist ja auch der delimiter)
D.h. wenn ich es mit "gesamte Zeile lesen, dann validieren" machen soll, muss etwas anderes her. Soll ich dann einfach ein '\n' oder anderen Whitespace (z.B ' ') anhängen, oder soll ich als Test nochmal versuchen einen char einzulesen, wenn dies gelingt ist es auch falsch (könnte aber problematisch werden, z.B. wenn man einfach ein Leerzeichen nach der Eingabe anfügt).Ich hab meinen Code mal angepasst, sieht jetzt so aus:
std::istream& operator>>(std::istream& is, ISBN& isbn) { std::string input; std::getline(is, input); input += ' '; // Findet man nach dem Einlesen whitespace, ist alles o.k. std::istringstream str{ input }; char ch1, ch2, ch3; str >> isbn.n1 >> ch1 >> isbn.n2 >> ch2 >> isbn.n3 >> ch3 >> isbn.x; if (!str) return is; if (ch1 != '-' || ch2 != '-' || ch3 != '-' || !std::isspace(str.peek())) { is.clear(std::ios_base::failbit); return is; } return is; }Könnte man das vorerstmal so lassen? Weiß halt nicht... das kommt mir wie ein unschöner Hack vor, das Anhängen von whitespace.
-
HarteWare schrieb:
Die Methode mit peek() funktioniert, wenn ich direkt aus dem istream lese, da ist der Zeilenumbruch wohl noch drin.
Dann lies doch einfach direkt aus dem std::istream. Wozu den Umweg über einen String?
-
@Nathan:
Den Umweg über String habe ich eingefügt, nachdem Shade of Mine geschrieben hat:Du liest die gesamte Zeile, dann validierst du sie.
Ich habe das so verstanden, dass ich mit getline das Ganze reinholen soll und dann bearbeiten. Jedoch ist mir nun, da du so fragst, die Idee gekommen, dass ich das falsch verstanden habe, und eigentlich etwas Anderes gemeint war.
@Shade Of Mine:
Hab ich das eventuell falsch verstanden?
-
@HarteWare: Du sprichst hier mit zwei verschiedenen Personen.
-
HarteWare schrieb:
@Nathan:
Den Umweg über String habe ich eingefügt, nachdem Shade of Mine geschrieben hat:Du liest die gesamte Zeile, dann validierst du sie.
Ich habe das so verstanden, dass ich mit getline das Ganze reinholen soll und dann bearbeiten. Jedoch ist mir nun, da du so fragst, die Idee gekommen, dass ich das falsch verstanden habe, und eigentlich etwas Anderes gemeint war.
Ja, aber du musst nicht jeden Vorschlag in dein Programm arbeiten. Du hast doch jetzt eine funktionierende Lösung. Bleib doch einfach dabei.
-
Nathan schrieb:
Ja, aber du musst nicht jeden Vorschlag in dein Programm arbeiten. Du hast doch jetzt eine funktionierende Lösung. Bleib doch einfach dabei.
Jaaa klar. Ich geb mich halt nie mit "funktioniert" zufrieden, sondern ich wills irgendwie auch gleich immer "richtig" machen. Aber das kommt bestimmt auch mit der Zeit... Naja ich erkläre das Thema mal als erledigt.