String zerteilen



  • Du könntest dir auch mal boost::tokenizer ansehen...



  • naja ich hab mir mal so ne funktion geschrieben:

    bool split(string& str, string splitter, string& out)
    {
      int pos;
      string temp;
      pos = str.find(splitter);
      if(pos != string::npos)
      {  
        temp = str;
        str.erase(pos, str.length()-1);
        out = temp;
        out.erase(0, pos + 1);
        return true;
      }
      return false;
    
    };
    

    aufrufen tut man sie so:

    string start = "Hallo!|wie gehts?";
    string endteil;
    split(start, "|", endteil;
    cout << start << "\n" << endteil << endl;
    

    naja zwar nicht perfekt, aber es funktioniert immerhin..

    mfg burnner



  • Hallo,

    tokenizer wurde ja schon genannt. Eine andere Möglichkeit wären Stringstreams:

    http://www.c-plusplus.net/forum/viewtopic.php?t=78596

    Wäre das nicht langsam mal was für die FAQ? Oder stehts da drin und ich habs übersehen? Die Frage gibts ja pro Woche mindestens ein mal....

    @burnner:
    Deine Lösung funktioniert aber auch nur beim ersten Trennzeichen.....



  • jo muss ich noch ändern...



  • So?

    bool split(string& str, string splitter, string& out, int position)
    { 
        string temp;
        temp = str;
        int i=0;
        int tem=0;
        int pos;
    
        while(tem < str.length())
        {    
    
           if(str[tem]== splitter[0])
           {    
    
              i++;   
    
              if(i == position)
              {
                 pos = tem;
              }
    
           }
           tem ++;
        }
    
      if(tem == str.length()-1)
        return false;
    
      str.erase(pos, str.length()-1);
      out = temp;
      out.erase(0, pos +1);
    
      return true;
    
    };
    

    hoffentlich^^

    burnner



  • evtl. auch sowas hier:

    // teilt einen String an bestimmten Zeichen und speichert die
    // Teilstrings in einer doppelt verketteten Liste
    std::deque<std::string> * split(const std::string & text, std::string delim)
    {
    std::string temp;
    std::string TXT = text;
    
    std::deque<std::string> * substrings = new std::deque<std::string>;
    	if (!substrings){std::cerr<<"Speicher konnte nicht angefordert werden"<<std::endl; exit(1);}
    
    	// solange die Zeichenkette, an der gesplittet werden soll
    	// in TXT vorhanden ist
    	while (TXT.find(delim) != std::string::npos)
    	{
    	// in temp die Zeichenkette bis zum Begrenzer speichern
    	temp = TXT.substr(0,TXT.find(delim));
    
    	// von TXT die in temp gespeicherte Zeichenkette und
    	// die Trennzeichenkette abschneiden
    	TXT = TXT.substr(temp.length() + delim.length());
    
    	substrings->push_back(temp);
    	}
    
    	// Die letzte Teilzeichenkette speichern
    	substrings->push_back(TXT);
    
    return substrings;
    }
    

    Nachteil:
    nicht besonders Idiotensicher, da man sich um's "deleten" der zurückgegebenen
    Liste selber kümmern muss 😕



  • meines sollte idiotensicher sein



  • Hi,

    erst mal ein Deque ist keine verkette Liste.

    ich hab das ganze mal Idiotensicher gemacht, und das deque durch ein list ersetzt

    // teilt einen String an bestimmten Zeichen und speichert die
    // Teilstrings in einer doppelt verketteten Liste
    std::list<std::string>  split(const std::string & text, std::string delim)
    {
        std::string temp;
        std::string TXT = text;
    
        std::list<std::string> substrings ;
    
        // solange die Zeichenkette, an der gesplittet werden soll
        // in TXT vorhanden ist
        while (TXT.find(delim) != std::string::npos)
        {
        // in temp die Zeichenkette bis zum Begrenzer speichern
        temp = TXT.substr(0,TXT.find(delim));
    
        // von TXT die in temp gespeicherte Zeichenkette und
        // die Trennzeichenkette abschneiden
        TXT = TXT.substr(temp.length() + delim.length());
    
        substrings.push_back(temp);
        }
    
        // Die letzte Teilzeichenkette speichern
        substrings.push_back(TXT);
    
    return substrings;
    }
    

    nun wird keine Zeiger mehr zurückgegeben, sondern eine Kopie

    grüße, Con@n



  • Warum sollte "deque" keine verkettete Liste sein????
    Is halt doppelt verkettet.



  • Hi,

    deque steht für "Double Ended Queue" Zu deutsch "Schlange mit zwei enden" und ist vom Aufbau her so ahnlich wie der Vector. Betonung liegt auf ähnlich. Er ist natürlich ein wenig Komplexer aufgebaut.

    grüße, Con@n



  • würde meine funktion nicht vollkommen genügen?

    mfg burnner



  • Merci an euch alle!
    Ihr habt mir wirklich sehr geholfen.

    Tschö,
    Karl



  • Con@n schrieb:

    Hi,

    deque steht für "Double Ended Queue" Zu deutsch "Schlange mit zwei enden" und ist vom Aufbau her so ahnlich wie der Vector. Betonung liegt auf ähnlich. Er ist natürlich ein wenig Komplexer aufgebaut.

    grüße, Con@n

    Aufbau is eher gar ned ähnlich zu vector.
    Sondern zu list:

    vector (normales Array):
    |---|---|---|---|---|
    |   |   |   |   |   |
    |---|---|---|---|---|
      /\
       |
    anfang
    
    =========================================================
    
    list (einfach verkettete Liste):
    
             |---|    |---|    |---|    |---|
    vorne -> |   | -> |   | -> |   | -> |   | -> 0
             |---|    |---|    |---|    |---|
    
    =========================================================
    
    deque (doppelt verkettete Liste):
    
        0 <- |---| <- |---| <- |---| <-  |---| <- hinten
             |   |    |   |    |   |     |   | 
    vorne -> |---| -> |---| -> |---| ->  |---| -> 0
    

    Aber is ja egal.
    Hauptsache es funktioniert 🙄



  • list ist bereits doppelt verkettet.
    Bei der deque ist das Einfügen und Löschen in der Mitte auch langsam. Nur vorne geht es eben schneller. Von daher ist sie näher am vector.


Anmelden zum Antworten