C 斯特托克为什么要警告警察?

C 斯特托克为什么要警告警察?,c,string,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 h

我对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);
应该打印

started with: this, is a test 
now have: , is a test
mystring是完全未被触及的,当然,我有一个指针指向它的一半,但这并不重要。那么为什么strtok抱怨我给它发送了一个const char*?

函数strtok修改它的参数。返回的指针位于原始字符串中。大小写中的分隔符将替换为\0字符。strtok的下一个调用不应该有一个字符串参数,而是一个空指针。但要小心:strtok使用一个分隔符字符串作为参数,而不是单个字符:

strtok(s, ','); //undefined behavior, interprets the ASCII value ',' as an address
strtok(s, ","); //correct
到底发生了什么? 让我们分析这个字符串:

"Hello magic world!\0"
我们如何在上面使用strtok

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

"Hello\0magic\0world!\0"
 ^      ^      ^
 |      |      |
first  second  third
您可以看到,3个指针可以用作以null结尾的常规字符串,但原始字符串在该过程中被销毁。putss现在只打印“你好”

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

Output:
Hello
Hello magic world!
函数strtok修改它的参数。返回的指针位于原始字符串中。大小写中的分隔符将替换为\0字符。strtok的下一个调用不应该有一个字符串参数,而是一个空指针。但要小心:strtok使用一个分隔符字符串作为参数,而不是单个字符:

strtok(s, ','); //undefined behavior, interprets the ASCII value ',' as an address
strtok(s, ","); //correct
到底发生了什么? 让我们分析这个字符串:

"Hello magic world!\0"
我们如何在上面使用strtok

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

"Hello\0magic\0world!\0"
 ^      ^      ^
 |      |      |
first  second  third
您可以看到,3个指针可以用作以null结尾的常规字符串,但原始字符串在该过程中被销毁。putss现在只打印“你好”

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

Output:
Hello
Hello magic world!
strtok不能在字符串文本上使用,否则会导致潜在的未定义行为。当您将const char*作为第一个参数传递时,编译器应该发出警告。这不是一个错误,这是一个设计缺陷

您的代码还有另一个问题:您将字符常量“”作为第二个参数传递,而不是字符串

要解析常量字符串,可以使用strspn和strcspn,它们返回大量字符,而无需修改字符串参数

以下是一个例子:

const char *mystring = "this, is a test";
size_t n1 = strcspn(mystring, ",");
size_t n2 = strspn(mystring + n1, ",");
char *newstring = strndup(mystring, n1);
printf("started with: %s\n rest of the string: %s\n", newstring, mystring + n1 + n2);
strtok不能在字符串文本上使用,否则会导致潜在的未定义行为。当您将const char*作为第一个参数传递时,编译器应该发出警告。这不是一个错误,这是一个设计缺陷

您的代码还有另一个问题:您将字符常量“”作为第二个参数传递,而不是字符串

要解析常量字符串,可以使用strspn和strcspn,它们返回大量字符,而无需修改字符串参数

以下是一个例子:

const char *mystring = "this, is a test";
size_t n1 = strcspn(mystring, ",");
size_t n2 = strspn(mystring + n1, ",");
char *newstring = strndup(mystring, n1);
printf("started with: %s\n rest of the string: %s\n", newstring, mystring + n1 + n2);

strtok实际上修改了参数。再次阅读文档:如果从该指针执行strcpy或printf,您将发现提供的字符串已在下一个分隔符处以NUL结尾。指针不是像你说的那样指向定界符,而是指向令牌的开头。@DarkAtom谢谢-基本的在线示例对此不是很清楚,但这实际上让我的生活轻松了很多。也许strtok没有正确找到定界符,因为你传递了“,”应该是,可能还包括一个空格。可能会有两个编译器警告。@BrydonGibson不要只看示例。也看看文档。strtok实际上修改了参数。再次阅读文档:如果从该指针执行strcpy或printf,您将发现提供的字符串已在下一个分隔符处以NUL结尾。指针不是像你说的那样指向定界符,而是指向令牌的开头。@DarkAtom谢谢-基本的在线示例对此不是很清楚,但这实际上让我的生活轻松了很多。也许strtok没有正确找到定界符,因为你传递了“,”应该是,可能还包括一个空格。可能会有两个编译器警告。@BrydonGibson不要只看示例。也请查看文档。