strtok, strtok_s
来自 cppreference.cn
在头文件 <string.h> 中定义 |
||
(1) | ||
char* strtok( char* str, const char* delim ); |
(直到 C99) | |
char* strtok( char* restrict str, const char* restrict delim ); |
(自 C99 起) | |
char* strtok_s( char* restrict str, rsize_t* restrict strmax, const char* restrict delim, char** restrict ptr ); |
(2) | (自 C11 起) |
将空终止字节字符串标记化。
1) 一系列对
strtok
的调用将 str 指向的字符串分解为一系列标记,每个标记都由 delim 指向的字符串中的字符分隔。序列中的每次调用都有一个搜索目标- 如果 str 非空,则该调用是序列中的首次调用。搜索目标是由 str 指向的空终止字节字符串。
- 如果 str 为空,则该调用是序列中的后续调用之一。搜索目标由序列中的前一次调用确定。
序列中的每次调用都在搜索目标中搜索不包含在 delim 指向的分隔符字符串中的第一个字符,分隔符字符串可能因调用而异。
如果 str 或 delim 不是指向空终止字节字符串的指针,则行为未定义。
2) 与 (1) 相同,但以下差异除外
- 在每次调用中,将 str 中剩余要查看的字符数写入 *strmax,并将 tokenizer 的内部状态写入 *ptr。
- 序列中的后续调用必须传递 strmax 和 ptr,其值为前一次调用存储的值。
- 以下错误在运行时检测到,并调用当前安装的 约束处理函数,而不在 ptr 指向的对象中存储任何内容
- strmax、delim 或 ptr 是空指针。
- 对于序列中的后续调用,*ptr 是空指针。
- *strmax 大于 RSIZE_MAX。
- 找到的标记的末尾未出现在搜索目标的前 *s1max 个字符内。
如果 str 指向缺少空字符的字符数组,并且 strmax 指向的值大于该字符数组的大小,则行为未定义。
与所有边界检查函数一样,仅当实现定义了 __STDC_LIB_EXT1__ 并且用户在包含 <string.h> 之前将 __STDC_WANT_LIB_EXT1__ 定义为整数常量 1 时,才能保证
strtok_s
可用。目录 |
[编辑] 参数
str | - | 指向要标记化的空终止字节字符串的指针 |
delim | - | 指向标识分隔符的空终止字节字符串的指针 |
strmax | - | 指向最初保存 str 大小的对象的指针:strtok_s 存储剩余要检查的字符数 |
ptr | - | 指向 char* 类型的对象的指针,strtok_s 使用它来存储其内部状态 |
[编辑] 返回值
1) 返回指向下一个标记的第一个字符的指针,如果没有标记,则返回空指针。
2) 返回指向下一个标记的第一个字符的指针,如果没有标记或存在运行时约束冲突,则返回空指针。
[编辑] 注意
此函数是破坏性的:它在字符串 str 的元素中写入 '\0' 字符。 特别是,字符串字面量不能用作 strtok
的第一个参数。
每次调用 strtok
都会修改静态变量:不是线程安全的。
与大多数其他标记器不同,strtok
中的分隔符对于每个后续标记可能不同,甚至可能取决于先前标记的内容。
strtok_s
函数与 POSIX strtok_r
函数的不同之处在于,它防止存储在被标记化的字符串之外,并通过检查运行时约束。 Microsoft CRT strtok_s
签名与此 POSIX strtok_r
定义匹配,而不是 C11 strtok_s
。
[编辑] 示例
运行此代码
#define __STDC_WANT_LIB_EXT1__ 1 #include <stdio.h> #include <string.h> int main(void) { char input[] = "A bird came down the walk"; printf("Parsing the input string '%s'\n", input); char* token = strtok(input, " "); while (token) { puts(token); token = strtok(NULL, " "); } printf("Contents of the input string now: '"); for (size_t n = 0; n < sizeof input; ++n) input[n] ? putchar(input[n]) : fputs("\\0", stdout); puts("'"); #ifdef __STDC_LIB_EXT1__ char str[] = "A bird came down the walk"; rsize_t strmax = sizeof str; const char* delim = " "; char* next_token; printf("Parsing the input string '%s'\n", str); token = strtok_s(str, &strmax, delim, &next_token); while (token) { puts(token); token = strtok_s(NULL, &strmax, delim, &next_token); } printf("Contents of the input string now: '"); for (size_t n = 0; n < sizeof str; ++n) str[n] ? putchar(str[n]) : fputs("\\0", stdout); puts("'"); #endif }
可能的输出
Parsing the input string 'A bird came down the walk' A bird came down the walk Contents of the input string now: 'A\0bird\0came\0down\0the\0walk\0' Parsing the input string 'A bird came down the walk' A bird came down the walk Contents of the input string now: 'A\0bird\0came\0down\0the\0walk\0'
[编辑] 参考文献
- C23 标准 (ISO/IEC 9899:2024)
- 7.24.5.8 strtok 函数 (p: TBD)
- K.3.7.3.1 strtok_s 函数 (p: TBD)
- C17 标准 (ISO/IEC 9899:2018)
- 7.24.5.8 strtok 函数 (p: TBD)
- K.3.7.3.1 strtok_s 函数 (p: TBD)
- C11 标准 (ISO/IEC 9899:2011)
- 7.24.5.8 strtok 函数 (p: 369-370)
- K.3.7.3.1 strtok_s 函数 (p: 620-621)
- C99 标准 (ISO/IEC 9899:1999)
- 7.21.5.8 strtok 函数 (p: 332-333)
- C89/C90 标准 (ISO/IEC 9899:1990)
- 4.11.5.8 strtok 函数
[编辑] 参见
在一个字符串中查找另一个字符串中任何字符的第一个位置 (函数) | |
返回由以下字符组成的最大初始段的长度 仅由在另一个字节字符串中未找到的字符组成 (函数) | |
返回由以下字符组成的最大初始段的长度 仅由在另一个字节字符串中找到的字符组成 (函数) | |
(C95)(C11) |
在宽字符串中查找下一个标记 (函数) |
C++ 文档 关于 strtok
|