strtok für C++



  • Hi Leute,

    ich versuche gerade mir eine strtok für C++ std::string selber zu coden, nur irgendwie komme ich noch nicht ganz mit den Pointer klar, was mach ich falsch?

    #include <iostream>
    #include <string>
    using namespace std;
    
    const string& stringtok(const string& source, const string& splitter)
    {
    	static string str;
    	static int start = -1, stop = -1;
    	static string result;
    
    	if (source.empty() == false)
    	{
    		str = source;
    	}
    	if (stop != -1)
    	{
    		start = str.find_first_not_of(splitter, stop);
    	}
    	else
    	{
    		start = str.find_first_not_of(splitter);
    	}
    	stop = str.find_first_of(splitter, start);
    	if (start != -1 && stop != -1)
    	{
    		result = str.substr(start, stop);
    		return result;
    	}
    	else
    	{
    		return NULL;
    	}
    }
    
    int main ()
    {
    	string last;
    	string current;
    	size_t found;
    
    	do {
    		// Eingabe
    		cin >> current;
    		// neuen String anhängen
    		last.append(current);
    		// String vor Bearbeitung ausgeben
    		cout << last << endl;
    		// String bearbeiten
    		cout << "start:" << endl;
    		string pch = stringtok(last, "a");
    		while (pch.empty() == false)
    		{
    			cout << pch << endl;
    			pch = stringtok(NULL, "a");
    		}
    		cout << pch << endl;
    		cout << "ende:" << endl;
    		// String einkürzen
    		found = last.find_last_of("&");
    		last = last.substr(found+1);
    		cout << last << endl;
    	} while (current != "");
    	// used in the same order as described above:
    
    	for (unsigned long i=0;i<100000000;i++);
    	return 0;
    }
    

    Gruß
    Scarabol



  • Hi Leute,

    hab mir jetzt folgende Funktion gebastelt, welche auch zu funktionieren scheint, währe aber trotzdem nett wenn sie nochmal jemand gegenliest und mir vielleicht einen Tip geben kann, was man verbessern kann...

    string* stringtok(string * source, const string& splitter)
    {
    	static string str;
    	static int start = -1, stop = -1;
    	static string result;
    
    	/*
    	if (start != -1 && stop == -1)
    	{
    		return NULL;
    	}
    	*/
    
    	if (source != NULL)
    	{
    		str = source->c_str();
    		start = -1;
    		stop = -1;
    	}
    	if (stop != -1)
    	{
    		start = str.find_first_not_of(splitter, stop);
    	}
    	else
    	{
    		start = str.find_first_not_of(splitter);
    	}
    	stop = str.find_first_of(splitter, start);
    	if (start != -1 && stop != -1)
    	{
    		result = str.substr(start, stop-start);
    		return &result;
    	}
    	/* letztes Element weglassen, falls kein Stop vorhanden
    	else if (start != -1 && stop == -1)
    	{
    		result = str.substr(start);
    		return &result;
    	}
    	*/
    	else
    	{
    		return NULL;
    	}
    }
    

    Gruß
    Scarabol



  • strtok sollte man gar nicht benutzen, das ist ja wirklich ekelhaft, wenn schon, dann pack das in eine Klasse und speicher den Zustand in einem Objekt.



  • Hehe, ich steh leider noch am Anfang daher hab ich bisher nur ne grobe Vorstellung was du meinst, aber ich benutze ja kein strtok sondern verwende mein eigenes...oder nicht?

    Ich werd mich bemühen, dass so schnell wie möglich zu realisieren...

    Gruß
    Scarabol



  • Hi!

    Ein Tipp (aber nicht von nem C++ Profi):
    Versuch nicht, C-Funktionen in C++ nachzuprogrammieren. Funktionalität nachzubilden ist eine sehr schöne Sache, aber versuche hier Klassen, Iteratoren, usw. zu nutzen. Die Nutzung sollte auch intuitiv sein (strtok finde ich nicht intuitiv, hatte Schwierigkeiten es ineinander zu verschachteln). Nacheinander viele if-Dinger sind unschön. Ich erkenne die verschiedenen Fälle, die auftreten könnnen, nicht.

    Wie schon Tippgeber meinte, benutz eine Klasse, indem du Zustände speicherst. Google mal ein wenig nach Implementierungen (c++ tokenizer). Schau dir auch mal an, wie die Boost-Bibliothek den Tokenizer implementiert.

    Viel Spaß
    Tobias Philipp



  • #include <string>
    #include <iostream>
    #include <vector>
    
    std::vector<std::string> TokenizeString(const std::string& str, const std::string& delim)
    {
        http://www.gamedev.net/community/forums/topic.asp?topic_id=381544
    	using namespace std;
    	vector<string> tokens;
    	size_t p0 = 0, p1 = string::npos;
    	while(p0 != string::npos)
    	{
    		p1 = str.find_first_of(delim, p0);
    		if(p1 != p0)
    		{
    			string token = str.substr(p0, p1 - p0);
    			tokens.push_back(token);
    		}
    		p0 = str.find_first_not_of(delim, p1);
    	}
    	return tokens;
    }
    
    int main()
    {
    	std::string SplitIt = "Split This String";
    	std::vector<std::string> split = TokenizeString( SplitIt, " " );
    
    	std::cout << split[0] << "\n"; // Split
    	std::cout << split[1] << "\n"; // This
    	std::cout << split[2] << "\n"; // String
    
    }
    

  • Administrator


Anmelden zum Antworten