String auf illegale Zeichen prüfen
-
Hi.
Ich will, dass ein String nur weiter verarbeitet wird, wenn er keine "illegalen" Zeichen beinhaltet. Ich übergebe dafür den String und die Liste der erlaubten Zeichen an meine Funktion isValidString.Die Funktion sieht so aus:
bool isStringValid(string myString, const char chars[]) { string::iterator sit; vector<char> validChars(chars, chars + sizeof(chars) / sizeof(char)); vector<char>::iterator vit; for(sit = myString.begin(); sit < myString.end(); sit++) { bool isValid = false; for(vit = validChars.begin(); vit < validChars.end(); vit++) { if(*sit == *vit) { isValid = true; break; } } if(!isValid) return false; } return true; }
Aus irgendwelchen Gründen funktioniert meine Funktion nur bei Strings mit einer Länge von max. 4 Zeichen. Bei 5 oder mehr Zeichen gibt die Funktion immer false zurück.
Aber woran kann das liegen?
Ich rufe die Funktion so auf:string str, chars; cout << "Bitte geben sie den Text ein: "; cin >> str; cout << "Bitte geben sie die erlaubten Zeichen ein: "; cin >> chars; if(isStringValid(str, chars.c_str())) { cout << "Der enigegeben Text wurde angenommen!" << endl; } else { cout << "Der eingegeben Text beinhaltet illegale Zeichen!" << endl; }
Woran kann das liegen? Ich habe wieder irgendeinen doofen Fehler, den ich selbst nicht sehe, im Verdacht. Ich hoffe, dass ihr mir helfen könnt.
LG
Cooter
-
Cooter schrieb:
sizeof(chars) / sizeof(char)
Was da steht ist folgendes: sizeof( char* ) / sizeof( char )
Ich denke mal deine Pointer haben 32 Bit also: 4 / 1 = 4
Lösung: Gib die Größe deiner Liste mit oder verwende besser gleich einen Container (vector, list etc.)
-
Warum ist dein zweites Argument ein char-Array und kein String? Dein Problem rührt daher:
sizeof(chars) / sizeof(char)
. Arrays in Funktionen funktionieren so nicht.edit: Zu langsam.
-
Habe ich mich auch gerade gefragt :p
Ich habe das jetzt mit 2 Strings und 2 Iteratorn gemachtKeine Ahnung wieso ich das zuerst anders gemacht habe - hatte wahrscheinlich die einzelnen Zeichen als Array im Hinterkopf und diese Möglichkeit nicht in Betracht gezogen.
Vielen Dank - jetzt läuft bei mir aber alles.
-
#include <string> #include <algorithm> bool isStringValid(std::string const &str, std::string const &invalid_elements) { return std::find_first_of(str.begin(), str.end(), invalid_elements.begin(), invalid_elements.end()) == str.end(); }
-
Danke sehr.
Sieht auf jeden Fall eleganter aus
Ich werde mir das mal ganz genau angucken.
-
Oder noch ein bisschen kürzer:
bool isStringValid( std::string const &str, std::string const &invalid_elements ) { return str.find_first_of( invalid_elements ) == std::string::npos; }
Die von wxSkip vorgeschlagene Verwendung von konstanten Referenzen macht auf alle Fälle Sinn um ein unnötiges Kopieren der Strings zu vermeiden.
Siehe dazu auch: http://www.parashift.com/c++-faq-lite/const-correctness.html
-
Danke.
Interessanter Link
-
Das Ganze kann man auch mit "regulären Ausdrücken" lösen. Entweder dein Compiler unterstützt schon "std::tr1::regex" oder man verwendet "boost::regex".
-
HighLigerBiMBam schrieb:
Das Ganze kann man auch mit "regulären Ausdrücken" lösen.
Das Ganze kann man auch mit Boost.Spirit lösen.
Nur ist beides viel umständlicher wie genau die Funktion anzuwenden, die dafür gedacht ist (Wobei Boost.Spirit hier sogar besser wie Regex wäre).
-
Und als ist besser als wie.
-
Danke sehr.
Ich gucke mir das alles mal genau an. Aber ich bleibe vorerst bei der ersten vorgestellten Lösung, bis ich besser C++ kann.