Strtok - Alternative?
-
Hallo liebe Community,
ich habe vor 3 Tagen angefangen mir C beizubringen und bin jetzt ueber die Funktion
char *strtok(char *str, const char *delim);
gestolpert.
Wenn ich das jetzt richtig verstanden habe, legt die Funktion die tokens aber in den Heap (Wikipedia sei gelobt, wie haben die Menschen frueher nur die Manpages ohne Wiki verstehen koennen??) des Betriebssystems.. Das kam mir alles sehr schaurig vor, weil mir die Daten soweit weg vorkommen... liege ich da falsch, dass man da eventuell bei Multitaskinganwendungen (threads oder aehnliches - ich bin auf dem Gebiet total unsichet, denn ich bin bis dahin noch nicht vorgedrungen...) zu Problemen stossen koennte?
Macht die folgende Funktion irgendwie Sinn? Oder hab ich eine andere Funktion neu erfunden? Gibt ja Raeder in vielen verschiedenen Ausfuehrungen...
/* -------> * STRING STRING OCCURRENCE * * gibt die Haeufigkeit eines String in einem anderen String * wieder zurueck. * Das ist praktisch, da man schnell herausfinden kann * in wieviele Teile man den String teilen moechte * und danni kann man dafuer dynamisch Speicher reservieren. * * Beispielcode: * * int main(void) * { * int anzahl = strstrocc("Der Mann auf dem Mond.", " "); * printf("%d", anzahl); * * return 0; * } * * Ergebnis: 4 */ int strstrocc(char *haystack, char *needle) { char *pos = NULL; int occ = 0; while ((pos = strstr(haystack, needle)) != NULL) { haystack = pos + strlen(needle); occ++; } return occ; } /* STRING TOKEN LONGEST * * Gibt den Laengsten gedachten Token wieder. * Berechnet werden die Token durch den gegebenen * String 'delim'. * */ int strtoklgst(char *str, char *delim) { char *tmp = (char *)malloc(strlen(str)+1); char *res; int size = 0; strcpy(tmp, str); while ((res = strsep(&tmp, delim)) != NULL) { if (strlen(res) > size) size = strlen(res); } free(tmp); return size; } /* STRING TOKENIZE * * Teilt einen String in mehrere Teile und packt diesen dann * in ein String-Array! YEAH! 3-facher Zeiger!! ;-) * * Argumente: * - token ist ein Zeiger auf das Stringarray (String: char *; String-Array: char **; Zeiger auf Stringarray: char ***) * - str ist der String, der geteilt werden soll * - delim bestimmt die Trennungszeichen, nach denen geteilt wird! * * Beispiel: * * int main(void) * { * char *str = "Ein Beispiel"; * char **token; * * strtokenize(&token, str, " "); * * printf("%s\n", token[0]); * printf("%s\n", token[1]); * * return 0; * } * * Ergebnis: Ein * Beispiel */ int strtokenize(char ***token, char *str, char *delim) { char *tmp = (char *)malloc(strlen(str)+1); strcpy(tmp, str); *token = (char **)calloc(strstrocc(tmp, delim)+2, strtoklgst(tmp, delim)+1); int pos = 0; while(((*token)[pos] = strsep(&tmp, delim)) != NULL) pos++; free(tmp); return 0; }
Ich hoffe die Kommentare stoeren nicht. Ist es ok so viele zu machen? Oder ist es zuviel? Weiss noch nicht so genau wo die Norm ist..
Hab noch ein paar weitere Funktionen fuer replace und insert geschrieben, da ich die passenden ANSI-C funktionen nicht gefunden habe, bzw der Meinung war, sie exisiteren nicht. Liege ich da falsch? Oder gibts noch irgendwo andere 'einfache' Bibliotheken? Obwohl... ich traue Bibliotheken nicht so ganz... _ Wenn ich son Monsterklopperding von GTK einbinden wuerde, wuerde mein Programm nicht langsamer werden? Bzw. ich seh bei solchen Dingern eh noch nicht durch..
Wenn die Fragen zu doof sind, tut's mir leid.
Liebe Gruesse und guten Rutsch,
euer GuttulaPS:
Ach noch ganz wichtig, weiss einer wo ich mir die Quelltexte zu den Bibliotheksfunktionen ansehe, bzw. wo die normalerweise im UNIX System gespeichert sind? Blick auch da noch nicht richtig durch... ganz ganz viel dank..
-
Kurz: strtok() ist nicht reentrantfähig. Deinen Code habe ich mir jetzt nicht angeschaut, aber unter Linux solltest du auch man: strtok_r finden. Das ist allerdings nicht ANSI C und demnach nicht portabel.
-
Danke, das Wort hat mir gefehlt. Aber:
BUGS
Avoid using these functions. If you do use them, note that:These functions modify their first argument.
These functions cannot be used on constant strings.
Heisst das, dass der str, den ich uebergebe, der ueberprueft werden soll, geaendert wird? Und dass ich nicht schreiben kann:
strtok_r("Ist das ein konstanter String?", " ", *strptr);
Uebrigens voll toll, wie schnell hier geantwortet wird!
-
Ja, das heisst das. strtok() und Konsorten sind nicht wirklich toll. Eine sauber implementierte, eigene Variante wäre sicher nicht schlechter
Edit: Andererseits muss man sich fragen wieviel Sinn es macht Stringliterale zu parsen