String in Wörter Trennen.
-
Hi zusammen,
ich habe folgenden String:
:pazifi!~pazifi@42DD1679.FFF4F829.250A8642.IP PRIVMSG #test :!action test test
Ich wollte Fragen, ob es möglich ist, nach "!action" nur das erste "test" einzulesen, welches zwischen den zwei Leerzeichen liegt. Sind mehr Leerzeichen da sollen die nicht extra beachtet werden, so dass man das reine Wort rausgekommt.
Also ich möchte vorallem fragen, welche Funktionen sich dazu am besten eignen und nach welchem Prinzip man da am besten vorgeht.
Bisher probierte ich es mit:
size_t pos = 0; if((pos=buffer.find(":!action"))!=string::npos) { string nick_in_aktion(buffer.substr(pos+6,pos+47)); }Das Problem ist aber, dass ich da grundsätzlich alle x-zeichen zwischen Position 1 und 2 bekomme...
Grüsse pazifi
-
Schritt 1: Finde das "!action" - hast du ja schon erledigt
Schritt 2: Finde den Anfang des Wortes - find_first_not_of()
Schritt 3: Finde das Ende des Wortes - find_first_of()
Schritt 4: Schneide dir den Abschnitt zwischen beiden Positionen aus - substr()
-
Vielen Dank für deine Hilfe.
Momentan probiere ich es nicht ganz erfolgreich so zu lösen:
size_t pos = 0; size_t pos1 = 0; size_t pos2 = 0; if((pos=buffer.find(":!action"))!=string::npos) { //anfang !action finden string nick_in_aktion(buffer.substr(pos+6,pos+47)); //nach aktion ausschneiden pos1 = nick_in_aktion.find_first_not_of(" "); //prüfen bis erstes zeichen kommt string nick_in_aktion1(nick_in_aktion.substr(pos1,41-pos1)); //ab dort ausschneiden pos2 = nick_in_aktion1.find_first_of(" "); // prüfen wann das leerzeichen an wortende kommt string nick_in_aktion2(nick_in_aktion1.substr(0,pos2)); //wortabschnitt ausschneiden }Solange ein Wort vorhanden ist, geht das gut, aber sobald kein Wort da ist, stürzt das Programm ab...
Der Compiler gibt kein Fehler beim Compilen aus.
-
Ja, bei den ganzen find...() Aufrufen solltest du auch abfangen, ob sie etwas gefunden haben (die geben grundsätzlich string::npos zurück, wenn nichts zu finden war).
-
Danke (o:
Jetzt gehts.
Ich musste die eine Zeile noch folgendermassen abfangen:
[cpp]
nick_in_aktion=buffer.substr(pos+befehl.size(),pos+47);
if((pos1 = nick_in_aktion.find_first_not_of(" "))!=string::npos) {
nick_in_aktion1=nick_in_aktion.substr(pos1,41-pos1);
pos2 = nick_in_aktion1.find_first_of(" ");
nick_in_aktion2=nick_in_aktion1.substr(0,pos2);
} else {
nick_in_aktion2="";
}
[/cpp]
-
Noch eine kleine Ergänzung: Es ist unnötig, noch viele Substrings als Zwischenspeicher zu erzeugen:
if((pos=buffer.find(":!action"))!=string::npos) { pos1 = buffer.find_first_not_of(" ",pos+6); if(pos1!=string::npos) { pos2=buffer.find_first_of(" ",pos1); nick=buffer.substr(pos1,pos2-pos1); } else nick=""; }
-
Danke für den letzen Tipp, hat mir das ganze Prozedere was ich gegen Ende hatte echt verkürzt.
Die Funktion macht jetzt folgendes:
Bei '!action' nimmt die den Nick von dem welcher den Befehl ausführt, ohne etwaige Leerzeichen zu Beginn und Ende.
Bei '!action nick' wird "nick" genommen, stehen andere wörter/nicks nach einen Leerzeichen werden die übergangen.
Bei '!action "nick und nick und bla"' wird alles zwischen den Anführungszeichen genommen. Steht hinter dem zweiten Anführungszeichen was, wirds übergangen.
Wird das abschliessende Anführungszeichen vergessen, wird nur bis zum ersten Leerzeichen ausgelesen.void action(string befehl, string handlung, const string &buffer) { size_t len = 0; size_t pos = 0; size_t pos1 = 0; size_t pos2 = 0; string nick_name(""); string ausgabe(""); //position des befehls auslesen pos = buffer.find(befehl); //länge des befehls auslesen len = befehl.length(); //prüfen ob " vorhanden if((buffer.find("\"")) != string::npos) { //wenn " vorhanden erstes " finden +1 damit selbst nicht mitgezählt pos1 = buffer.find_first_of("\"")+1; //prüfen ob mit " abgeschlossen wurde if((buffer.find("\"",pos1)) != string::npos) { //wenn ja ende bei " pos2 = buffer.find_first_of("\"",pos1); } else { //wenn nein ende bei ersten leerzeichen nach " pos2 = buffer.find_first_of(" ",pos1); } } else if (buffer.find_first_not_of(" ",pos+len) != string::npos) { //wenn kein " vorhanden erste leerstelle nach befehl finden pos1 = buffer.find_first_not_of(" ",pos+len); //zweite leerstelle nach befehl pos2 = buffer.find_first_of(" ",pos1); } else { //wenn kein nick nach befehl, nick vom schreiber nehmen pos1=1; pos2=buffer.find("~")-1; } //nick auschneiden nick_name=buffer.substr(pos1,pos2-pos1); [...] }Ich denke somit wäre die Frage vollständig gelöst. Danke nochmals!