char Vector in wörter zerlegen (oder in string umwandeln, dann in wörter zerlegen)



  • Hallo leute,

    ich habe in einen Programm folgende Methode implementiert:

    void conn::rd(){
    
     vector<char> buf (128);
     int bytes = recv(sock,&buf[0],buf.size()-1,0);
    
     if (bytes==-1)
     {
      perror("Error")
     }
    
     cout<<"erhalten"<<&buf[0]<<"\n";
    }
    

    Wie schon der Titel besagt, möchte ich die lange char kette in einzelne Wörter zerlegen. Ich denke persönlich, dass das viel komplizierter wäre, als ob ich ein char vector in einen string vector konvertiere und dann in wörter zerlege!

    Ich habe aber keine AHNUNG bezüglich der konvertierung! Das in wörter zerlegen in string kriege ich schon hin... Bitte hilft mir, bin am verzweifeln 😡



  • Warum muss es unbedingt char sein. std::string mit den Funktionen find und substr können dies!



  • Du kannst den Inhalt in einen string kopieren, wenn Du dafür eine fertige Lösung hast und die Kosten der Kopie ok sind.

    std::string s(buf.begin(), buf.end());
    

    Du kannst auch etwas wie boost::tokenizer benutzen. Das kann mit jedem Iterator. Oder etwas entsrpechendes selber schreiben.


  • Mod

    Ein ketzerischer Vorschlag: Füg am Ende noch eine Null an und benutze dann strtok.



  • SeppJ schrieb:

    Ein ketzerischer Vorschlag: Füg am Ende noch eine Null an und benutze dann strtok.

    ... und bedenke, dass das nicht mehr funktioniert, wenn das im Multithreading verwendet werden soll. 😉

    Gruß,

    Simon2.



  • brotbernd schrieb:

    Du kannst den Inhalt in einen string kopieren, wenn Du dafür eine fertige Lösung hast und die Kosten der Kopie ok sind.

    std::string s(buf.begin(), buf.end());
    

    Du kannst auch etwas wie boost::tokenizer benutzen. Das kann mit jedem Iterator. Oder etwas entsrpechendes selber schreiben.

    Wohl eher

    std::string s(buf.begin(), buf.begin() + readBytes);
    

    🙂



  • Simon2 schrieb:

    ... und bedenke, dass das nicht mehr funktioniert, wenn das im Multithreading verwendet werden soll. 😉

    Was aber kein spezifisches Problem von strtok() ist. Die ganze Standardbibiothek ist momentan nicht threadsicher.


  • Mod

    Nexus schrieb:

    Simon2 schrieb:

    ... und bedenke, dass das nicht mehr funktioniert, wenn das im Multithreading verwendet werden soll. 😉

    Was aber kein spezifisches Problem von strtok() ist. Die ganze Standardbibiothek ist momentan nicht threadsicher.

    Wobei es dann auch wieder manchmal threadsichere Versionen davon gibt. Da muss man dann die Compilerhandbücher für lesen. Ich habe sogar threadsichere Versionen von strtok gefunden (C Runtime von Solaris, also der Sun Compiler).



  • Für sowas gibt es boost::algorithm::split.



  • strtok_s() bei MSVS z.B.



  • Schau dir mal die stringstreams an:

    istringstream iss (std::string(&buf[0]));
    iss >> word[0] >> word[1] >> word[2] >> ...;
    

    Ist leider relativ langsam (wie der Rest von der C++ iostreamlib).

    Das allerletze, was du tun solltest, ist strtok_s() zu verwenden.



  • Hallo,

    voerst möchte ich micht für die zahlreichen Antworten und Ideen bedanken!

    ... Könnt ihr mir das mal mit String in meine Methode einfügen ? (Das Problem besteht, dass ich es gestern auch so versucht habe und nicht funktioniert hat und möchte wissen wie ihr das dan so machtr)...

    hier ist nochmal die Methode :

    void conn::rd(){ 
    
     vector<char> buf (128); 
     int bytes = recv(sock,&buf[0],buf.size()-1,0); 
    
     if (bytes==-1) 
     { 
      perror("Error") 
     } 
    
     cout<<"erhalten"<<&buf[0]<<"\n"; 
    }
    

    - Ich hatte bezüglich der Wörtertrennung was anderes, was wesentlich aufwendiger ist. Wie funktiniert das genau mit der Methode von euch ?

    Vielen Dank für den Super Support in Cplusplus, den ich sonst niergends erhalte!



  • std::string s(buf.begin(),buf.begin()+bytes);
    

    Dies funktioniert, wenn sizeof(BYTE)==sizeof(char) .
    Eine Möglichkeit, wäre es, wie istri gezeigt hat, über std::stringstreams zu gehen, eine Andere:

    template<class F1, class F2> inline
    F1 find_first_not_of(const F1& first1, const F1& last1,
    					 const F2& first2, const F2& last2) 
    {
    	F1 fir = first1;
    	for (; fir != last1; ++fir)
    	{
    		F2 mid2;
    		for (mid2 = first2; mid2 != last2; ++mid2)
    			if (*fir == *mid2)
    				break;
    		if(mid2==last2)
    			return(fir);
    	}
    	return (fir);
    }
    
    bool Split(const std::string& org, const std::string& separators, std::vector<std::string>& words)
    {
    	std::string::const_iterator en, be=org.begin();
    	do
    	{
    		en=find_first_of(be,org.end(), separators.begin(),separators.end());
    		if(be!=en)
    		{
    			words.push_back("");
    			for(std::string::const_iterator i=be; i!=(en); ++i)
    				words.back()+=*i;
    		}
    		be=find_first_not_of(en,org.end(),
    			separators.begin(),separators.end());
    	} while(be!=org.end());
    
    	return(words.size()?true:false);
    }
    
    int main()
    {
        std::string str("Hallo,     wie geht es dir\tdenn heute so?");
    	std::vector<std::string> v;
    	if(Split(str," ",v))
    	{
    		for(size_t i=0;i<v.size();++i)
    			std::cout << v[i] << endl;
    	}
    	v.clear();
    	std::cout << "------------------------\n";
    	if(Split(str," ,.?\t",v))
    	{
    		for(size_t i=0;i<v.size();++i)
    			std::cout << v[i] << endl;
    	}
    }
    

    Erzeugt die Ausgabe

    Hallo,
    wie
    geht
    es
    dir     denn
    heute
    so?
    ------------------------
    Hallo
    wie
    geht
    es
    dir
    denn
    heute
    so
    

    Du könntest Split() umschreiben, sodass die Funktion mit Iteratoren arbeitet und der vector buf direkt verwendet werden kann. Auch getestet mit Codepad.



  • Hallo Vicious,

    vielen Dank voerst!

    Ok, dass es sehr aufschlussreich!
    Meine Frage ist nun, wie und was übergebe ich von meiner Funktion (rd) an die Funktion find_first_not_of ?

    Das Problem ist einfach, dass die Funktion von mir gewisse Abhängigkeiten hat und nur mit der recv Methode was am Socket empfängt und ich nicht genau weiss wie ich das an deine Funktion anhänge bzw. wo ?!?



  • Hallo nochmal,

    ok das mit den String convertieren klappt reibungslos.

    Das mit den Wörter zerlegen ist etwas missverstanden wurden 🙂 Sorry mein Fehler... Und zwar will dich den String in Teilstringsschneiden die durch UCF-8 codierte zeichen getrennt sind!



  • Vicious Falcon schrieb:

    Dies funktioniert, wenn sizeof(BYTE)==sizeof(char) .

    Also immer.


Log in to reply