[C++] String teilen und bestimmte Zeichen entfernen

Nerran

Grünschnabel
Moin,
Ich habe momentan einen std::string aus dem ich 1. Einige zeichen entfernen will (Kommata um genau zu sein). Und 2. Ihn danach bei Leerzeichen Trennen will. (strtok akzeptiert nur char* und beim umwandeln crasht das Programm...) Wie geht das? :)
Nachtrag:
Code:
void Income(string msg){
	cout << msg;
	char * buffer = new char[msg.length()+1];
	strcpy(buffer,msg.c_str());
	char* pToken = strtok(buffer,": ");
	string test = pToken;
	cout << test;
	if(test == "Extract"){	
		pToken = strtok(buffer,"Extract: ");
		string test = pToken;
	/*	
	//	cout << endl << test << endl;
		string ex = "extr";
		ex += test;
		send(ex);
	*/
		cout << "Message == Extract!";

	}
	
}
Wieso crasht es jedesmal wenn Income mit dem Parameter Extract aufgerufen wird?
 
Zuletzt bearbeitet:
Ein Token ist ein Teilstring, der zwischen zwei Trennzeichen steht (das Stringende mal mitgerechnet). strtok hat als ersten Parameter den zu durchsuchenden String, und als zweiten Parameter einen String, in dem die Trennzeichen definiert sind.
Zum 1. Parameter: Der String wird nur beim ersten Aufruf übergeben, nachfolgende Aufrufe müssen mit null erfolgen.
Zum 2. Parameter: Jedes einzelne Zeichen wird als Trennzeichen interpretiert. Folgen mehrere Trennzeichen im Suchstring unmittelbar hintereinander auf, werden diese als ein einziges Trennzeichen behandelt. Der String mit den Trennzeichen kann auch pro Aufruf unterschiedlich sein.
Zum Rückgabewert: wird kein nichtleerer Teilstring ohne Trennzeichen gefunden, wird null zurückgeliefert, ansonsten ein Zeiger auf das Token.

Das Programm stürzt in dem if-Zweig ab. Der buffer enthält den String "Extract", der String mit den Trennzeichen enthält "Extract: ". strtok findet also in dem buffer nur Trennzeichen und kein Token; deswegen ist der Rückgabewert und somit auch pToken null. Beim Verwenden des null-Pointers zwecks Erstellung eines string-Objektes stürzt das Programm ab.
 
d.h. folgender code müsste funktionieren ?(Komme erst am 2 . wieder an nen compilet )
Code:
void Income(string msg)
{
	cout << msg;
	char * buffer = new char[msg.length()+1];
	strcpy(buffer,msg.c_str());
	char* pToken = strtok(buffer,": ");
	string test = pToken;	cout << test;
	if(test == "Extract"){
		pToken = strtok(NULL,"Extract: ");
                              if(pToken) {
                    		string test = pToken;
                    		cout << endl << test << endl;
	               	string ex = "extr";
		               ex += test;
                		send(ex);
                      		cout << "Message == Extract!";
                             }
	}
}
 
Jein. Absturzsicher ist er, allerdings bezweifle ich, dass die Semantik der Intention entspricht. Oder anders gesagt: das Programm wird wahrscheinlich nicht das tun, was du von ihm erhoffst.
Durch die Verwendung des NULL-Parameters stellst du sicher, dass der buffer nach weiteren Tokens durchsucht wird. Allerdings wird, weil du "Extract: " als String der zu verwendenden Trennzeichen übergibst, nur die Teilstrings als Token erkannt, die weder 'E' noch 'x' noch 't' noch 'r' noch... beinhalten. Hatte der buffer ursprünglich nur den String "Extract" als Inhalt, wird pToken weiterhin NULL sein und die innere if-Anweisung nicht erfüllt sein.
Als String für Trennzeichen solltest du nur die Zeichen verwenden, die die nachfolgenden Daten voneinander abgrenzen; beispielsweise wäre für eine csv-Datei möglicherweise " ;\t" geeignet.
Wenn du nur am kompletten Reststring interessiert bist, probierst du vielleicht am besten, den Leerstring "" als Trennzeichenstring zu verwenden.
Unter http://www.cplusplus.com/reference/clibrary/cstring/strtok/ findest du auch eine kurze Beschreibung von strtok. Vielleicht verwendest du aber auch lieber eine der dort erwähnten Funktionen strcspn und strcspn. Allerdings ist strtok, sobald man sie richtig zu handhaben weiß, meistens die komfortabelste Möglichkeit, einen String zu zerteilen. Wenn du aber auch leere Datenfelder berücksichtigen willst bzw. musst, ist sie höchstwahrscheinlich ungeeignet, da, wie oben erwähnt, mehrere aufeinanderfolgende Trennzeichen als eines verwertet werden. Eventuell kann sie trotzdem im Zusammenspiel mit den oben erwähnten Funktionen (strcspn und strcspn) sehr nützlich sein. Jedenfalls solltest du dich mit der Methodik von strtok vertraut machen, um auch für künftige Anwendungen entscheiden zu können, ob und in welcher Weise sie dir dienlich sein kann
 
Zuletzt bearbeitet:
Zurück