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!


Anmelden zum Antworten