std::strtok
来自 cppreference.cn
定义于头文件 <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"
[编辑] 参见
查找分隔符集合中任何字符的第一个位置 (函数) | |
返回最大初始段的长度,该段由 仅由在另一个字节字符串中未找到的字符组成 (函数) | |
返回最大初始段的长度,该段由 仅由在另一个字节字符串中找到的字符组成 (函数) | |
一个 view ,用于查看通过使用分隔符拆分另一个 view 获得的子范围(类模板) (范围适配器对象) | |
C 文档 关于 strtok
|