Namespaces
Variants

std:: strtok

From cppreference.net
ヘッダーで定義 <cstring>
char * strtok ( char * str, const char * delim ) ;

ヌル終端バイト文字列をトークン化します。

std::strtok への一連の呼び出しは、 str が指す文字列を、 delim が指す文字列中の文字で区切られたトークンのシーケンスに分割します。このシーケンスにおける各呼び出しには 検索対象 があります:

  • str が非nullの場合、この呼び出しはシーケンスにおける 最初の呼び出し となります。検索対象は str が指すnull終端バイト文字列です。
  • str がnullの場合、この呼び出しはシーケンスにおける 後続の呼び出し の一つとなります。検索対象はシーケンス内の前回の呼び出しによって決定されます。

シーケンス内の各呼び出しは、検索対象から delim が指す セパレータ文字列 に含まれ ない 最初の文字を検索します。セパレータ文字列は呼び出しごとに異なる場合があります。

  • そのような文字が見つからない場合、検索対象にはトークンが存在しません。シーケンス内の次回呼び出し時の検索対象は変更されません。 [1]
  • そのような文字が見つかった場合、それが現在のトークンの開始位置となります。 std::strtok はその後、区切り文字列に含まれる最初の文字を検索します。
    • そのような文字が見つからない場合、現在のトークンは検索対象の終端まで延長されます。シーケンス内の次回呼び出し時の検索対象は空文字列となります。 [2]
    • そのような文字が見つかった場合、その文字はヌル文字で上書きされ、これにより現在のトークンが終了します。シーケンス内の次回呼び出し時の検索対象は次の文字から開始されます。

str または delim がnull終端バイト文字列へのポインタでない場合、動作は未定義です。

  1. 異なる区切り文字列を用いた後続の呼び出しでトークンが形成される可能性があります。
  2. 後続の呼び出しではこれ以上トークンを形成できません。

目次

翻訳の説明: - 「Contents」を「目次」に翻訳しました - C++関連の専門用語(Parameters, Return value, Notes, Possible implementation, Example, See also)は原文のまま保持しました - HTMLタグ、属性、クラス名、ID、リンク先は一切変更していません - 数値や書式設定は完全に保持しています

パラメータ

str - トークン化するヌル終端バイト文字列へのポインタ
delim - 区切り文字を指定するヌル終端バイト文字列へのポインタ

戻り値

次のトークンの最初の文字へのポインタを返します。トークンが存在しない場合はヌルポインタを返します。

注記

この関数は破壊的です:文字列 str の要素に ' \0 ' 文字を書き込みます。特に、 string literal 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
(クラステンプレート) (レンジアダプタオブジェクト)