名稱空間
變體
操作

std::strtok

來自 cppreference.com
< cpp‎ | string‎ | byte
在標頭檔案 <cstring> 中定義
char* strtok( char* str, const char* delim );

對空終止的位元組字串進行分詞。

std::strtok 進行一系列呼叫,將由 str 指向的字串分解為一系列詞元,每個詞元都由 delim 指向的字串中的字元分隔。序列中的每次呼叫都有一個 搜尋目標

  • 如果 str 非空,則該呼叫是序列中的 首次呼叫。搜尋目標是由 str 指向的空終止位元組字串。
  • 如果 str 為空,則該呼叫是序列中的 後續呼叫 之一。搜尋目標由序列中的上一次呼叫決定。

序列中的每次呼叫都會在搜尋目標中查詢第一個包含在由 delim 指向的分隔符字串中的字元,分隔符字串可以隨每次呼叫而不同。

  • 如果沒有找到這樣的字元,則搜尋目標中沒有詞元。序列中下一次呼叫的搜尋目標保持不變。[1]
  • 如果找到這樣的字元,它就是當前詞元的開頭。然後 std::strtok 從那裡開始搜尋第一個包含在分隔符字串中的字元。
    • 如果沒有找到這樣的字元,當前詞元延伸到搜尋目標的末尾。序列中下一次呼叫的搜尋目標是一個空字串。[2]
    • 如果找到這樣的字元,它將被空字元覆蓋,該空字元終止當前詞元。序列中下一次呼叫的搜尋目標從下一個字元開始。

如果 strdelim 不是指向空終止位元組字串的指標,則行為未定義。

  1. 詞元仍然可以在後續呼叫中使用不同的分隔符字串形成。
  2. 後續呼叫中無法再形成更多詞元。

目錄

[編輯] 引數

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 庫,在 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