std:: strtok
|
定义于头文件
<cstring>
|
||
|
char
*
strtok
(
char
*
str,
const
char
*
delim
)
;
|
||
对以空字符结尾的字节字符串进行分词处理。
一系列对
std::strtok
的调用会将
str
所指向的字符串分解为若干标记序列,每个标记均由
delim
所指向字符串中的字符进行分隔。该调用序列中的每次操作均具有一个
搜索目标
:
- 如果 str 非空,该调用是序列中的 首次调用 。搜索目标是由 str 指向的以空字符结尾的字节字符串。
- 如果 str 为空,该调用是序列中的 后续调用 之一。搜索目标由序列中的前一次调用确定。
序列中的每次调用都会在搜索目标中查找第一个 不 包含在由 delim 指向的 分隔字符串 中的字符,该分隔字符串在每次调用时可以不同。
- 如果未找到这样的字符,则搜索目标中不存在任何令牌。序列中下一次调用的搜索目标保持不变。 [1]
-
如果找到这样的字符,它即为当前令牌的起始位置。
std::strtok随后从该位置开始搜索首个包含在分隔符字符串中的字符。- 如果未找到这样的字符,当前令牌将延伸至搜索目标的末尾。序列中下一次调用的搜索目标为空字符串。 [2]
- 如果找到这样的字符,该字符将被空字符覆盖,从而终止当前令牌。序列中下一次调用的搜索目标从后续字符开始。
如果 str 或 delim 不是指向以空字符结尾的字节字符串的指针,则行为未定义。
目录 |
参数
| str | - | 指向要标记化的以空字符结尾的字节字符串的指针 |
| delim | - | 指向标识分隔符的以空字符结尾的字节字符串的指针 |
返回值
返回指向下一个令牌首字符的指针,若无令牌则返回空指针。
注释
此函数具有破坏性:它会在字符串
str
的元素中写入
'
\0
'
字符。特别需要注意的是,
字符串字面量
不能用作
std::strtok
的第一个参数。
每次调用此函数都会修改静态变量:非线程安全。
与大多数其他分词器不同,
std::strtok
中的分隔符对于每个后续标记可以各不相同,甚至可以依赖于先前标记的内容。
可能的实现
char* strtok(char* str, const char* delim) { static char* buffer; if (str != nullptr) buffer = str; buffer += std::strspn(buffer, delim); if (*buffer == '\0') return nullptr; char* const tokenBegin = buffer; buffer += std::strcspn(buffer, delim); if (*buffer != '\0') *buffer++ = '\0'; return tokenBegin; } |
实际的C++库实现将此函数委托给C标准库,其实现方式可能为直接实现(如 MUSL libc 所示),或基于其可重入版本实现(如 GNU libc 所示)。
示例
#include <cstring> #include <iomanip> #include <iostream> int main() { char input[] = "one + two * (three - four)!"; const char* delimiters = "! +- (*)"; char* token = std::strtok(input, delimiters); while (token) { std::cout << std::quoted(token) << ' '; token = std::strtok(nullptr, delimiters); } std::cout << "\nContents of the input string now:\n\""; for (std::size_t n = 0; n < sizeof input; ++n) { if (const char c = input[n]; c != '\0') std::cout << c; else std::cout << "\\0"; } std::cout << "\"\n"; }
输出:
"one" "two" "three" "four" Contents of the input string now: "one\0+ two\0* (three\0- four\0!\0"
参见
|
查找分隔符集合中任意字符的首次出现位置
(函数) |
|
|
返回仅包含不在另一字节字符串中的字符的最大初始段长度
(函数) |
|
|
返回仅包含在另一字节字符串中存在的字符的最大初始段长度
(函数) |
|
|
(C++20)
|
通过使用分隔符拆分另一
view
获得的子范围的
view
(类模板) (范围适配器对象) |
|
C 文档
用于
strtok
|
|