string find (Vielleicht falsches Forum)



  • Hallo!

    Ich weiß noch nicht ganz sicher, ob das hier das richtige Forum ist... sorry, wenn nicht!

    Ich habe einen string, der so aussieht:

    TextCarriagereturnTextCarriageReturnCarriageReturnText etc...

    Ich möchte jetzt gerne jede jeden "Text" durch die void TuWasDamit jagen.
    Ich bekomme es irgendwie nicht hin, die Zeile richtig zu splitten.

    Kann mir bitte jemand sagen, was ich hier falsch mache?
    Vielen Dank!

    void DoSomething(string data)
    {
    	int b = 0;
    	int iPos = data.find("\r");
    	string s = "";
    
    	for(;;)
    	{
    		if (iPos == -1)
    		{
    			break;
    		}
    		s = data.substr(b,iPos-b);
    		TuWasDamit(s);
    		b = iPos+1;
    		iPos = data.find("\r",iPos-b);
    	}
    }
    


  • ps: Ich freue mich auch, wenn mir jemand sagt, wie man es (abgesehen von meinem wohl offensichtlichen Fehler) besser macht.
    Dass ich Anfänger bin, ist wohl relativ offensichtlich.

    Danke!



  • Woher bekommst du denn deine Daten? Möglicherweise aus einer Datei?



  • Ja. Das klappt auch gut.
    Aber mit dem iPos und dem b stimmt was nicht.


  • Mod

    Deine Zeile 16 scheint ein bisschen durcheinander zu sein. Möchtest du da nicht von Position b an suchen?

    Ich habe jetzt nicht nach weiteren Fehlern gesucht, habe stattdessen deine Idee (die an sich schon ganz gut ist) nochmal sauber umgesetzt:

    #include <string>
    #include <iostream>
    
    using namespace std;
    
    void TuWasDamit(string data)
    {
      cout << data << '\n';
    }
    
    void DoSomething(string data)
    {
      size_t prev = 0;  // Position des Zeichens nach dem letzten '\r'
    
      // next: Position des nächsten '\r'
      for(size_t next = data.find('\r', prev); next != string::npos; next = data.find('\r', prev))
        {
          TuWasDamit(data.substr(prev, next-prev));
          prev = next + 1;
        }
    
      if (prev < data.size()) // Falls der String nicht auf '\r' endete.
        TuWasDamit(data.substr(prev));
    } 
    
    int main()
    {
      DoSomething("Hallo\rWelt\r!\rDu\rbist\rso\rgrausam\r\rPlenk\r\r.");
    }
    

    Ist das gleiche wie deines, etwas weniger chaotisch und weniger unnötige Zwischenwerte. Und einen Sonderfall, den du vergessen hast noch eingefügt.

    Das sollte sich auch leicht auf eine beliebige Liste von Delimitern verallgemeinern lassen, indem man find_first_of anstatt find nimmt. Und anstatt TuWasDamit aufzurufen, kann man natürlich ein allgemeines Funktionsobjekt aufrufen oder den Token in einen Outputiterator schreiben. Aber das ist eher fortgeschrittener Stoff.



  • hermieweber schrieb:

    Ja. Das klappt auch gut.
    Aber mit dem iPos und dem b stimmt was nicht.

    Dann könntest du es auch so machen:

    void DoSomething(std::istream& data)
    {
       std::string text;
       while(std::getline(data, text, '\r'))
          TuWasDamit(text);
    }
    
    int main()
    {
       std::ifstream daten("Daten.txt");
       DoSomething(daten);
    }
    

Anmelden zum Antworten