命名空间
变体
操作

std::strtok

来自 cppreference.com
< cpp‎ | string‎ | byte
定义在头文件 <cstring>
char* strtok( char* str, const char* delim );

在由 str 指向的以 null 结尾的字节字符串中查找下一个标记。 分隔符由由 delim 指向的以 null 结尾的字节字符串标识。

此函数旨在被多次调用以从同一个字符串中获取连续的标记。

  • 如果 str 不是空指针,则该调用将被视为对该特定字符串的第一个 strtok 调用。 该函数搜索第一个包含在 delim 中的字符。
  • 如果未找到此类字符,则 str 中根本没有标记,该函数返回一个空指针。
  • 如果找到了此类字符,则它是标记的开头。 然后该函数从该点开始搜索第一个包含delim 中的字符。
  • 如果未找到此类字符,则 str 只有一个标记,对 strtok 的未来调用将返回一个空指针。
  • 如果找到了此类字符,则它会被替换为 null 字符 '\0',指向下一个字符的指针将存储在一个静态位置,以便后续调用使用。
  • 然后,该函数返回指向标记开头的指针。
  • 如果 str 是一个空指针,则该调用被视为对 strtok 的后续调用:该函数从上次调用结束的地方继续。 行为与将之前存储的指针传递给 str 相同。

内容

[编辑] 参数

str - 指向要标记的以 null 结尾的字节字符串的指针
delim - 指向标识分隔符的以 null 结尾的字节字符串的指针

[编辑] 返回值

指向下一个标记的开头,或 nullptr,如果不再有标记。

[编辑] 备注

此函数具有破坏性:它会在字符串 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 库,在 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