为什么 strtok 对 const 发出警告?

Bry*_*son 1 c string

我对strtok的理解是它返回一个指向char数组(char*)中第一个分隔符的指针。

我收到针对 const char* 作为参数的警告,但我不明白为什么这很重要 - strtok 根本不修改参数。

我的理解:

const char* mystring = "this, is a test";
char* endstring = strtok(mystring, ',');
char* newstring = strdup(endstring);
printf("started with: %s\n now have: %s\n", mystring, newstring);
Run Code Online (Sandbox Code Playgroud)

应打印

started with: this, is a test 
now have: , is a test
Run Code Online (Sandbox Code Playgroud)

mystring 完全未受影响,当然,我有一个指向其中一半的指针,但这并不重要。那么为什么 strtok 抱怨我向它发送了一个 const char* 呢?

Dar*_*tom 5

该函数strtok()修改它的参数。返回的指针位于原始字符串内。分隔符(在您的情况下,)被替换为一个\0字符。下一次调用strtok()不应有字符串参数,而应有NULL指针。但要小心:strtok()采用一串分隔符作为参数,而不是单个字符:

strtok(s, ','); //undefined behavior, interprets the ASCII value ',' as an address
strtok(s, ","); //correct
Run Code Online (Sandbox Code Playgroud)

到底发生了什么?

我们来分析一下这个字符串:

"Hello magic world!\0"
Run Code Online (Sandbox Code Playgroud)

我们如何使用strtok()它呢?

char s[] = "Hello magic world!"
char* first = strtok(s, " ");
char* second = strtok(NULL, " ");
char* third = strtok(NULL, " ");
Run Code Online (Sandbox Code Playgroud)

让我们看看标记化后的字符串:

"Hello\0magic\0world!\0"
 ^      ^      ^
 |      |      |
first  second  third
Run Code Online (Sandbox Code Playgroud)

您可以看到,这 3 个指针可以用作常规的空终止字符串,但原始字符串在此过程中被破坏。puts(s)现在只打印“Hello”。

printf("%s\n", s);
printf("%s %s %s\n", first, second, third);

Output:
Hello
Hello magic world!
Run Code Online (Sandbox Code Playgroud)