std::string zerlegen



  • Hi!

    Brauche Hilfe!

    Ich habe einen String der sich bspw. so zusammensetzt:

    "Bla1 1 2 3 4 5
    Bla2 9 8 7
    Bla4 12 22"

    Mein Problem:

    1. Ich muß diesen String "zeilenweise" also bis zum "/r/n" auslesen und

    2. diese Zeile dann an eine Funktion übergeben, die mir alle weiteren Inhalte in Variablen wieder zurückgibt, deren Anzahl (!) variieren kann!

    Bsp:

    std::string str = "Bla1 1 2 3 4 5" // beinhaltet 6 Variablen-Inhalte
    

    Die Funktion soll mir nun Bla1 und 1 und 2 und 3 und 4 und 5 in insgesamt 6 Variablen zurückliefern, damit ich diese dann in meinem Programm einsetzen kann.

    Wenn ich dann aber

    std::string str = "Bla2 9 8 7" // beinhaltet ja nur 4 Variablen-Inhalte
    

    komme ich ins Schleudern.

    Wie kann man solch ein Problem am elegantesten lösen?

    Ich hoffe ich konnte mein Problem verständlich darlegen.

    Gruß
    Bernhard

    P.s.: Ich benutze nicht die MFC (also kein CString) und setze auch nicht strtok oder dergleichen ein. Benutze z.Z. Visual c++ 6.0
    Deswegen habe ich auch in dieses Forum gemailt und hoffe auch damit richtig zu liegen



  • Das hier sollte dir helfen:
    Humes Lösung



  • Hab sowas auch schon mal benötigt um Dozenten aus einer Textdatei zu lesen.

    int read(vector<string> &doz,string *src)
    {
       int i=0,pos=0;
       do doz.push_back(src->substr(pos,src->find(';',pos)-pos));
       while((++pos+=doz[i].length())&&++i&&i<count(src->begin(),src->end(),';'));
       return i;
    }
    


  • was soll das string*? const string& halte ich fuer angemessener.



  • Und hier das gleiche ohne count 🙂

    template<class output, class input>
    void explode(output& v, const input& s, input::value_type d)
    {
    	input::const_iterator i = s.begin();
    	while(true)
    	{
    		input::const_iterator c = i;
    		i = std::find(i, s.end(), d);
    		v.push_back(output::value_type(c, i));
    
    		if(i == s.end())
    			break;
    		++i;
    	}
    }
    
    int main(int argc, char* argv[])
    {
    	std::vector<std::string> v;
    	std::string t("bla;bla2;bla3");
    
    	std::cout << t << std::endl;
    	explode(v, t, ';');
    	std::cout << v.size() << ": ";
    	std::copy(v.begin(), v.end(), std::ostream_iterator<std::string>(std::cout, " "));
    	std::cout << std::endl;
    
    	return 0;
    }
    


  • PeterTheMaster schrieb:

    was soll das string*? const string& halte ich fuer angemessener.

    Da man bei der Übergabe &myString schreiben miß wird deutlich das in diesen String etwas geschrieben wird....



  • Knuddlbaer schrieb:

    PeterTheMaster schrieb:

    was soll das string*? const string& halte ich fuer angemessener.

    Da man bei der Übergabe &myString schreiben miß wird deutlich das in diesen String etwas geschrieben wird....

    Das wird es doch gar nicht 😕



  • @tag

    Wozu die templates ?
    Hab meine alte Version nochmal überarbeitet.
    Anzahl dann auch mit vector.size() 😃

    void explode(vector<string> &v,const string &s,const char &sep)
    {
       int pos=0;
       do v.push_back(s.substr(pos,s.find(sep,pos)-pos));
       while((++pos+=v[v.size()-1].length())&&pos<s.length());
    }
    


  • _Stefan schrieb:

    Wozu die templates ?
    [/cpp]

    Weils praktischer ist, wenn man die Teilstrings auch in einer list statt einem vector speichern kann.



  • kann man auch so.....



  • Erst in einen vector schreiben lassen und dann in eine list kopieren? Oder gleich die list nach vector casten? 😉



  • wie man es halt braucht. 🙄



  • Gut das wir das geklärt hätten.



  • ...davon abgesehen soll es tatsächlich Leute geben, die std::wstring verwenden.



  • tag schrieb:

    template<class output, class input>
    void explode(output& v, const input& s, input::value_type d)
    {
    

    es muss
    typename input::value_type
    heissen, denn input::value_type ist ein dependet type (haengt von einem template parameter ab)


Anmelden zum Antworten