Problem: Suchen in Strings
-
Hallo,
ich habe ein Problem beim Durchsuchen eines Strings:
Eine Datei wird zeilenweise eingelesen, sie ist immer nach dem folgenden Schema aufgebaut:
KEY | value | comment
Ich möchte sowohl den Key, als auch den Value und den Comment herauslesen. Theoretisch ist es auch kein Problem und funktioniert soweit.
Nun sind diese Dateien allerdings nicht immer vollkommen gleich, d.h. manchmal stehen mehr Leerzeichen oder ein Tabstopp, manchmal steht gar kein Leerzeichen dazwischen und manchmal besteht der value selbst aus mehreren Wörtern mit Leerzeichen getrennt.Beispiele: KEY |value |comment KEY | value| comment KEY |value|comment KEY |value value| comment usw...Der Beginn des Value ist einfach. Ich suche nach dem 1. "|" und dann nach dem 1. Zeichen, das kein Leerzeichen ist (find_first_not_of(' ')).
Aber gibt es auch eine Möglichkeit, von dem 2. "|" rückwärts nach dem 1. Zeichen zu suchen, das kein Leerzeichen ist?Ich habe schon diverse Möglichkeiten ausprobiert, aber ich habe es noch nicht geschafft, dass es dann wirklich für alle vorkommenden Fälle funktioniert...
Wie würdet Ihr denn da vorgehen?
Vielen Dank schon mal!
-
Zerlege deinen String doch erstmal in Teilstrings mit Leerzeichen und lösche diese dann erst nachträglich raus. Das ist wahrscheinlich einfacher und sinnvoller, als in dem gesamten String hin und her zu navigieren. Zu dem Zweck kannst du dir ja eine kleine trim-Funktion aus find_first_not_of, erase usw. basteln, die am Anfang und am Ende abschneidet.
EDIT:
Ich benutze zwar so gut wie nie std::string (entweder CString oder char*), habe aber mal ein bisschen 'rumprobiert und im Rahmen meiner Möglichkeiten eine kleine Trim-Funktion gebastelt:
void Trim(std::string *s) { size_t pos=s->find_first_not_of(' '); if(pos!=s->npos) { s->erase(s->begin(),s->begin()+pos); } std::basic_string <char>::reverse_iterator rIter=s->rbegin(); while(*rIter++==' ') { s->erase(s->end()-1); } }Na los, ihr std::string-Profis, reißt meine Funktion in Stücke!
-
Hat denn keiner was zu meckern? Dann muss meine Funktion wohl nahe an der Perfektion sein...

-
_matze schrieb:
Dann muss meine Funktion wohl nahe an der Perfektion sein
Bei weitem nicht

-
KasF schrieb:
_matze schrieb:
Dann muss meine Funktion wohl nahe an der Perfektion sein
Bei weitem nicht

Dann sag, was nicht in Ordnung ist. Wenn ich schonmal std::string benutze, will ich auch was dabei lernen.

-
_matze schrieb:
Dann sag, was nicht in Ordnung ist.
Oder ich zeig dir, wie's schöner aussehen könnte:
string trim(const string& str) { string::size_type pos = str.find_first_not_of(" \n\t"); //etc.. was man will if(pos != string::npos ) return str.substr(pos, str.find_last_not_of(" \n\t") - pos + 1); return str; }Edit: Wobei man mit isspace noch mehr rausholen könnte, such einfach mal was im Forum

-
@LadyM: Verwende op>> und du hast viele Probleme weniger ...
-
KasF schrieb:
_matze schrieb:
Dann sag, was nicht in Ordnung ist.
Oder ich zeig dir, wie's schöner aussehen könnte:
string trim(const string& str) { string::size_type pos = str.find_first_not_of(" \n\t"); //etc.. was man will if(pos != string::npos ) return str.substr(pos, str.find_last_not_of(" \n\t") - pos + 1); return str; }Edit: Wobei man mit isspace noch mehr rausholen könnte, such einfach mal was im Forum

Hmm, ja, sieht schöner aus. Und ist auch ein klein wenig schneller (980ms zu 34000ms!
).