1. 说明
1.1 函数签名如下:
char * strtok ( char * str, const char * delimiters );
- str : 要被分解成一组小字符串的字符串。
- delimiters : 包含分隔符的 C 字符串。
1.2 返回值:
该函数返回被分解的一个子字符串,如果没有可检索的字符串,则返回一个空指针。
1.3 使用方法:
- 第1次调用时,第1个参数要传入1个C的字符串,作为要分割的字符串
- 后续调用时,第1个参数设置为空指针NULL
- 上一个被分割的子字符串的位置会被函数内部记住,所以后续调用时,第1个参数设置为NULL
1.4 分割字符串的原理
- 子字符串的起点是第1个不含分隔符的字符
- 子字符串的终点是起点之后第1个含有分隔符的字符,或者整个字符串的终止字符
- 如此往复
2. 头文件
#include
3. 例子-分解字符串
#include
#include
int main () {
char str[80] = "This is - www.runoob.com - website";
const char s[2] = "-";
char *token;
/* 获取第一个子字符串 */
token = strtok(str, s);
/* 继续获取其他的子字符串 */
while( token != NULL ) {
printf( "%s\n", token );
token = strtok(NULL, s);
}
return 0;
}
结果:
This is
www.runoob.com
website
4. strtok_s
使用时strtok
可能会报错,说strtok
是不安全的函数,建议使用strtok_s
:
error C4996: 'strtok': This function or variable may be unsafe. Consider using strtok_s instead. To disable deprecation, use _CRT_SECURE_NO_WARNINGS.
strtok
要记住上一个子字符串的位置,所以多线程使用时不安全。
上述报错可以通过设置_CRT_SECURE_NO_WARNINGS
预处理定义来解决。
也可以替换成使用strtok_s
来解决。
strtok_s
的签名如下:
char* strtok_s(char* str, const char* delimiters, char** next_token);
strtok_s
多了一个参数next_token
,strtok_s
把剩下的字符串写到next_token
里,这样内部就不用记录子字符串等信息了,从而是线程安全的函数。
把上面的例子改成使用strtok_s
,如下:
#include
#include
int main()
{
char str[80] = "This is - www.runoob.com - website";
const char s[2] = "-";
char *token;
char *next_token = NULL;
/* 获取第一个子字符串 */
token = strtok_s(str, s, &next_token);
/* 继续获取其他的子字符串 */
while (token != NULL) {
printf("%s\n", token);
token = strtok_s(NULL, s, &next_token);
}
return 0;
}
结果:
This is
www.runoob.com
website
5. 参考
http://www.cplusplus.com/reference/cstring/strtok/
https://www.runoob.com/cprogramming/c-function-strtok.html
https://docs.microsoft.com/en-us/cpp/c-runtime-library/reference/strtok-s-strtok-s-l-wcstok-s-wcstok-s-l-mbstok-s-mbstok-s-l?view=vs-2019