String zerteilen
-
Hallo,
ich bin auf der Suche nach einer Methode, die einen String an definierbaren Stellen, z.B. bei einem Zeichen "|", zerteilt.
Ich habe schon gegoogelt, da habe ich was gefunden: allerdings wurde ein Char* zerteilte.
Ich habe also zwei Fragen:
- Wie zerteile ich einen String (wie ober genannt)?
- Wie finde ich Informationen zu bestimmten Befehlen, oder wie finde ich Befehle, wenn ich nur weiss, was am Ende rauskommen soll? Gibt es eine gute Site/Buch/sonstige Technik?
Oftmals finde ich in der FAQ oder per Such-Funktion dieses Forums Antworten. Leider ist diese aber momentan ausser Betrieb.
Vielen Dank,
Karl
-
eine referenz findest du hier: http://www.cppreference.com/
und suchen solltest du nachfind( )
und
substr( )
-
Selbst schreiben
Zählen, bis du das gewünschte Zeichen findest, dann einen String mit dieser Größe erstellen und alles bis dahin rein. Ab dem Zeichen wird weiter gezählt und noch ein zweiter String erstellt mit der entsprechenden Größe. Da dann den Rest reinkopieren und du hast es. Die class-Members von CString helfen dir da imho nicht weiter.
Du kannst auch probieren, das ganze geschickt mit Vector zu machen oder du baust dir C-Strings (char* foo)...
-
Du könntest dir auch mal boost::tokenizer ansehen...
-
naja ich hab mir mal so ne funktion geschrieben:
bool split(string& str, string splitter, string& out) { int pos; string temp; pos = str.find(splitter); if(pos != string::npos) { temp = str; str.erase(pos, str.length()-1); out = temp; out.erase(0, pos + 1); return true; } return false; };
aufrufen tut man sie so:
string start = "Hallo!|wie gehts?"; string endteil; split(start, "|", endteil; cout << start << "\n" << endteil << endl;
naja zwar nicht perfekt, aber es funktioniert immerhin..
mfg burnner
-
Hallo,
tokenizer wurde ja schon genannt. Eine andere Möglichkeit wären Stringstreams:
http://www.c-plusplus.net/forum/viewtopic.php?t=78596
Wäre das nicht langsam mal was für die FAQ? Oder stehts da drin und ich habs übersehen? Die Frage gibts ja pro Woche mindestens ein mal....
@burnner:
Deine Lösung funktioniert aber auch nur beim ersten Trennzeichen.....
-
jo muss ich noch ändern...
-
So?
bool split(string& str, string splitter, string& out, int position) { string temp; temp = str; int i=0; int tem=0; int pos; while(tem < str.length()) { if(str[tem]== splitter[0]) { i++; if(i == position) { pos = tem; } } tem ++; } if(tem == str.length()-1) return false; str.erase(pos, str.length()-1); out = temp; out.erase(0, pos +1); return true; };
hoffentlich^^
burnner
-
evtl. auch sowas hier:
// teilt einen String an bestimmten Zeichen und speichert die // Teilstrings in einer doppelt verketteten Liste std::deque<std::string> * split(const std::string & text, std::string delim) { std::string temp; std::string TXT = text; std::deque<std::string> * substrings = new std::deque<std::string>; if (!substrings){std::cerr<<"Speicher konnte nicht angefordert werden"<<std::endl; exit(1);} // solange die Zeichenkette, an der gesplittet werden soll // in TXT vorhanden ist while (TXT.find(delim) != std::string::npos) { // in temp die Zeichenkette bis zum Begrenzer speichern temp = TXT.substr(0,TXT.find(delim)); // von TXT die in temp gespeicherte Zeichenkette und // die Trennzeichenkette abschneiden TXT = TXT.substr(temp.length() + delim.length()); substrings->push_back(temp); } // Die letzte Teilzeichenkette speichern substrings->push_back(TXT); return substrings; }
Nachteil:
nicht besonders Idiotensicher, da man sich um's "deleten" der zurückgegebenen
Liste selber kümmern muss
-
meines sollte idiotensicher sein
-
Hi,
erst mal ein Deque ist keine verkette Liste.
ich hab das ganze mal Idiotensicher gemacht, und das deque durch ein list ersetzt
// teilt einen String an bestimmten Zeichen und speichert die // Teilstrings in einer doppelt verketteten Liste std::list<std::string> split(const std::string & text, std::string delim) { std::string temp; std::string TXT = text; std::list<std::string> substrings ; // solange die Zeichenkette, an der gesplittet werden soll // in TXT vorhanden ist while (TXT.find(delim) != std::string::npos) { // in temp die Zeichenkette bis zum Begrenzer speichern temp = TXT.substr(0,TXT.find(delim)); // von TXT die in temp gespeicherte Zeichenkette und // die Trennzeichenkette abschneiden TXT = TXT.substr(temp.length() + delim.length()); substrings.push_back(temp); } // Die letzte Teilzeichenkette speichern substrings.push_back(TXT); return substrings; }
nun wird keine Zeiger mehr zurückgegeben, sondern eine Kopie
grüße, Con@n
-
Warum sollte "deque" keine verkettete Liste sein????
Is halt doppelt verkettet.
-
Hi,
deque steht für "Double Ended Queue" Zu deutsch "Schlange mit zwei enden" und ist vom Aufbau her so ahnlich wie der Vector. Betonung liegt auf ähnlich. Er ist natürlich ein wenig Komplexer aufgebaut.
grüße, Con@n
-
würde meine funktion nicht vollkommen genügen?
mfg burnner
-
Merci an euch alle!
Ihr habt mir wirklich sehr geholfen.Tschö,
Karl
-
Con@n schrieb:
Hi,
deque steht für "Double Ended Queue" Zu deutsch "Schlange mit zwei enden" und ist vom Aufbau her so ahnlich wie der Vector. Betonung liegt auf ähnlich. Er ist natürlich ein wenig Komplexer aufgebaut.
grüße, Con@n
Aufbau is eher gar ned ähnlich zu vector.
Sondern zu list:vector (normales Array): |---|---|---|---|---| | | | | | | |---|---|---|---|---| /\ | anfang ========================================================= list (einfach verkettete Liste): |---| |---| |---| |---| vorne -> | | -> | | -> | | -> | | -> 0 |---| |---| |---| |---| ========================================================= deque (doppelt verkettete Liste): 0 <- |---| <- |---| <- |---| <- |---| <- hinten | | | | | | | | vorne -> |---| -> |---| -> |---| -> |---| -> 0
Aber is ja egal.
Hauptsache es funktioniert
-
list ist bereits doppelt verkettet.
Bei der deque ist das Einfügen und Löschen in der Mitte auch langsam. Nur vorne geht es eben schneller. Von daher ist sie näher am vector.