...
Because strtok() modifies it's argument, the string is subsequently unsafe and cannot be used in its original form. If you need to preserve the original string, copy it into a buffer and pass the address of the buffer to strtok() instead of the original string.
Non-Compliant Code Example
| Code Block | ||
|---|---|---|
| ||
char *path = getenv("PATH");
/* PATH is something like "/usr/bin:/bin:/usr/sbin:/sbin" */
char *token;
token = strtok(path, ":");
puts(token);
while (token = strtok(0, ":")) {
puts(token);
}
printf("PATH: %s\n", path);
/* PATH is now just "/usr/bin" */
|
In this example, the strtok() function is used to parse the first argument into colon-delimited tokens; it will output each word from the string on a new line. However, after the while loop ends, path will have been modified to look like this: "/usr/bin\0/bin\0/usr/sbin\0/sbin\0". This is an issue on several levels. If we check our local path variable, we will only see /usr/bin now. Even worse, we have unintentionally changed the environment variable PATH, which could cause unintended results.
Compliant Solution
One possible solution is to copy the string being tokenized into a temporary buffer which isn't referenced after the calls to strtok():
...
Never use this function. This function modifies its first argument. The identity of the delimiting character is lost. This function cannot be used on constant strings.
References
| Wiki Markup |
|---|
\[[ISO/IEC 9899-1999:TC2|AA. C References#ISO/IEC 9899-1999TC2]\] Section 7.21.5.8, "The strtok function" Unix Man page strtok(3) |