strtok - Problem mit Rückgabewert
-
Hallo,
ich arbeite mit der strtok (strtok_s) Funktion um einen String zu splitten und dann die einzelnen Werte in eine Struktur zu kopieren.
Leider kommt es aber immer wieder zu Fehlern weil die strtok() Funktion nicht den richtigen Rückgabewert liefert.
strtok() liefert komischerweise bei mir nie NULL zurück, d.h. das Programm strützt im weiteren Verlauf ab weil mit falschen Werten gearbeitet wird.
Kleines Beispiel:char *p=NULL; p = strtok(message,":"); if(p == NULL) //nur komischerweiße kommt es NIE dazu das p = NULL ist return 1;
p liefert mit immer nicht gleich NULL zurück selbst wenn das Trennzeichen überhaupt nicht im String vorhanden ist.
Kann mir jemand erklären was da falsch läuft?
Wo liegt den mein Fehler ?
Weiß echt nicht mehr so recht weiter..
-
Bitte poste ein vollständiges, kompilier- und ausführbares Minibeispiel.
-
char message[] = "Test1|Test2"; char *p = NULL; p = strtok(message,":"); if(p == NULL) //p zeigt jetzt aber auf die adresse von message return 1;
Bei dem Beispiel oben kommt es wirklich nie dazu das p gleich NULL ist.
Kann mir jemand warum das so ist ?
-
Ich vermute jetzt einfach mal Du hast nicht verstanden wie strtok eingesetzt wird.
http://www.cplusplus.com/reference/clibrary/cstring/strtok/
http://de.wikibooks.org/wiki/C-Programmierung:_Zeichenkettenfunktionen/* strtok example */ #include <stdio.h> #include <string.h> int main () { char str[] ="- This, a sample string."; char * pch; printf ("Splitting string \"%s\" into tokens:\n",str); pch = strtok (str," ,.-"); while (pch != NULL) { printf ("%s\n",pch); pch = strtok (NULL, " ,.-"); } return 0; }
Beachte das strtok in der WHILE Schleife im weiteren Verlauf mit NULL gerufen wird.
Weiterhin:
Du solltest strtok vermeiden, da es nicht reentrant ist.http://stackoverflow.com/questions/4031075/strtok-function-thread-safety
EDIT:
Bei dem Beispiel oben kommt es wirklich nie dazu das p gleich NULL ist.
Kann mir jemand warum das so ist ?Das ist auch richtig so. Hier darf kein NULL Zeiger zurück kommen. Das erste Token in Deinem Beispiel ist nun mal nicht leer.
-
Ich vermute jetzt einfach mal Du hast nicht verstanden hast wie strtok eingesetzt wird.
Ich habe sowohl verstanden wie strtok() eingesetzt wird.
Das Problem ist einfach wenn beim ersten Aufruf von strtok das Trennzeichen nicht im String vorhanden das strtok() nicht NULL zurück liefert.Das ist auch richtig so. Hier darf kein NULL Zeiger zurück kommen. Das erste Token in Deinem Beispiel ist nun mal nicht leer.
Das heißt strtok liefert nie beim ersten Aufruf NULL zurück ?
Dann muss ich wohl mittels strpbrk() vorher überprüfen ob das Trennzeichen überhaupt in dem String vorkommt.Du solltest strtok vermeiden, da es nicht reentrant ist.
Dafür gibts ja schließlich strtok_s.
-
Dafür gibts ja schließlich strtok_s.
Bei Microsoft VC++ ja. Woanders, möglicherweise nicht, weiß ich jetzt auch nicht so genau. Es gibt aber auch noch strtok_r
http://www.mkssoftware.com/docs/man3/strtok_r.3.asp
EDIT:
Hier noch eine mögliche Implementierung von strtok. Damit wird dann auch klar warum da nicht NULL zurück gegeben wird ;).
http://www.koders.com/c/fid4BE42498019181532F7F7A05702D7120CDE48B38.aspx
Hier auch nochmal schauen
http://www.imb-jena.de/~gmueller/kurse/c_c++/c_strtok.html
Der erste Aufruf von strtok überspringt führende Trennzeichen, liefert einen Zeiger auf den Anfang des ersten gefundenen Token in string1 zurück und setzt ein NULL-Zeichen unmittelbar hinter das Token-Ende. Folgende Aufrufe von strtok mit dem Wert NULL anstelle des Arguments string1 liefern Zeiger auf weitere Token. Wenn kein weiteres Token gefunden wird, liefert strtok den Wert NULL. Der String wurde dann vollständig analysiert.
-
Für VC++ 2010
Nach MSDN ist strtok reentrent.
strtok_s bietet Schutz gegen Bufferüberlauf.
strtok_r (posix) gibts es bei VC nicht.
-
Shiba schrieb:
Nach MSDN ist strtok reentrent.
Nur für statisch gegen CRT gelinkte Programme. (nicht Voreinstellung in VStudio)