strtok
函数用于将一个大字符串分割成多个子字符串(标记)。每次调用 strtok
函数都会返回下一个标记(子字符串),直到没有更多的标记为止。
函数原型:
char *strtok(char *restrict s, const char *restrict delim);
s
: 指向待分割字符串的指针。首次调用时,应指向要分割的整个字符串;后续调用时,应当传入NULL,strtok会继续从上一次的位置开始查找。delim
: 指向一个包含分隔符字符的字符串,strtok
将这些字符作为分割点。
行为特点:
strtok
在找到一个分隔符后,会将其替换为'\0'
字符(空字符),从而使得当前标记成为一个独立的字符串。内部维护了一个静态变量来跟踪上次分割的位置,所以连续调用
strtok
可以遍历整个字符串的所有标记。
注意:
使用
strtok
时要注意线程安全问题,因为它使用了静态存储区保存状态。在多线程环境中应考虑使用strtok_r
(POSIX扩展)或strtok_s
(在C11标准中定义的安全版本)。
示例:
例 1:普通写法。
#include <stdio.h>
#include <string.h>
int main()
{
char str[] = "Hello, World! This is a test string.";
char delimiters[] = ", .! ";
char *result_arr[32] = {};
int idx = 0;
// 首次调用,传递待分割字符串的首地址
result_arr[idx] = strtok(str, delimiters);
while (result_arr[idx] != NULL)
{
// 继续查找下一个标记,此时传入NULL
result_arr[++idx] = strtok(NULL, delimiters);
}
idx = 0;
while (result_arr[idx] != NULL)
{
printf("%s\n", result_arr[idx++]);
}
}
例 2:简写。
#include <stdio.h>
#include <string.h>
int main()
{
char str[] = "Hello, World! This is a test string.";
char delimiters[] = ", .! ";
char *result_arr[32] = {str};
int idx = 0;
while ((result_arr[idx] = strtok(result_arr[idx], delimiters)) && ++idx)
;
idx = 0;
while (result_arr[idx] != NULL)
{
printf("%s\n", result_arr[idx++]);
}
}
例 3:封装成函数。
#include <stdio.h>
#include <string.h>
int msg_deal(char *msg_src, char *msg_done[], char delemiters[])
{
int len = 0;
while ((msg_done[len] = strtok(msg_done[len], delemiters)) && ++len)
;
return len;
}
int main()
{
char str[] = "Hello, World! This is a test string.";
char *result_arr[32] = {str};
int len = msg_deal(str, result_arr, ", .! ");
// printf("len: %d\n", len); // 7
int i = 0;
while (result_arr[i] != NULL)
{
printf("%s\n", result_arr[i++]);
}
}
例 1 和 例 2 的结果相同,运行代码后,输出将是:
Hello
World
This
is
a
test
string
每个单词都被当作单独的标记打印出来,这是因为逗号、句号、感叹号和空格都是我们的分隔符。
评论区