std::strtok
From cppreference.com
| ヘッダー <cstring> で定義 |
||
| char* strtok( char* str, const char* delim ); |
||
ヌル終端されたバイト文字列をトークン化する。
std::strtokの連続する呼び出しは、strが指す文字列をトークンのシーケンスに分割します。各トークンはdelimが指す文字列の文字によって区切られます。シーケンス内の各呼び出しには「検索対象」があります。
- strがヌルでない場合、その呼び出しはシーケンスにおける「最初の呼び出し」です。検索対象はstrが指すヌル終端されたバイト文字列です。
- strがヌルの場合、その呼び出しはシーケンスにおける「後続の呼び出し」の1つです。検索対象はシーケンス内の前の呼び出しによって決定されます。
シーケンス内の各呼び出しは、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ライブラリに委譲されており、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を区切り文字で分割して得られる部分rangeに対する view(クラステンプレート) (rangeアダプタオブジェクト) | |
| strtokのCドキュメント
| |