strtok, strtok_s
From cppreference.com
| ヘッダー <string.h> で定義 |
||
| (1) | ||
char* strtok( char* str, const char* delim ); |
(C99まで) | |
| char* strtok( char* restrict str, const char* restrict delim ); |
(C99以降) | |
| char* strtok_s( char* restrict str, rsize_t* restrict strmax, const char* restrict delim, char** restrict ptr ); |
(2) | (C11 以降) |
ヌル終端されたバイト文字列をトークン化します。
1)
strtok の一連の呼び出しは、str が指す文字列をトークンのシーケンスに分割します。各トークンは delim が指す文字列の文字によって区切られます。シーケンス内の各呼び出しには検索対象があります。- str がヌルでない場合、その呼び出しはシーケンスにおける最初の呼び出しです。検索対象は str が指すヌル終端されたバイト文字列です。
- str がヌルである場合、その呼び出しはシーケンスにおける後続の呼び出しの1つです。検索対象はシーケンス内の前の呼び出しによって決定されます。
シーケンス内の各呼び出しは、delim が指す区切り文字列に含まれていない最初の文字を検索対象内で探します。区切り文字列は呼び出しごとに異なる場合があります。
str または delim がヌル終端されたバイト文字列へのポインタでない場合、動作は未定義です。
2) 以下の違いを除いて、(1) と同じです。
- 各呼び出しで、str 内に残っている文字数を *strmax に書き込み、トークナイザの内部状態を *ptr に書き込みます。
- シーケンス内の後続の呼び出しでは、前の呼び出しによって格納された値で strmax と ptr を渡す必要があります。
- 以下のエラーは実行時に検出され、ptr が指すオブジェクトに何も格納せずに、現在インストールされている制約ハンドラ関数を呼び出します。
- strmax、delim、または ptr がヌルポインタである。
- シーケンス内の後続の呼び出しで *ptr がヌルポインタである。
- *strmax が RSIZE_MAX より大きい。
- 見つかったトークンの末尾が、検索対象の最初の *s1max 文字内にない。
str がヌル文字を持たない文字配列を指し、かつ strmax がその文字配列のサイズよりも大きい値を指す場合、動作は未定義です。
すべての境界チェック付き関数と同様に、
strtok_s は、実装によって __STDC_LIB_EXT1__ が定義され、ユーザーが <string.h> をインクルードする前に __STDC_WANT_LIB_EXT1__ を整数定数 1 に定義している場合にのみ利用可能であることが保証されます。目次 |
[編集] パラメータ
| str | - | トークン化するヌル終端されたバイト文字列へのポインタ |
| delim | - | 区切り文字を識別するヌル終端されたバイト文字列へのポインタ |
| strmax | - | 最初に str のサイズを保持するオブジェクトへのポインタ: strtok_s は、残りの文字数を格納します。 |
| ptr | - | char* 型のオブジェクトへのポインタ。strtok_s がその内部状態を格納するために使用します。 |
[編集] 戻り値
1) 次のトークンの最初の文字へのポインタを返します。トークンがない場合はヌルポインタを返します。
2) 次のトークンの最初の文字へのポインタを返します。トークンがない場合、または実行時制約違反がある場合はヌルポインタを返します。
[編集] 注釈
この関数は破壊的です。文字列 str の要素に '\0' 文字を書き込みます。特に、文字列リテラルを strtok の最初の引数として使用することはできません。
strtok の各呼び出しは静的変数を変更するため、スレッドセーフではありません。
他のほとんどのトークナイザとは異なり、strtok の区切り文字は後続の各トークンで異なり、前のトークンの内容に依存することさえあります。
strtok_s 関数は、トークン化される文字列の外部への格納を防ぎ、実行時制約をチェックするという点で、POSIX のstrtok_r 関数とは異なります。Microsoft CRT のstrtok_s のシグネチャは、C11 の strtok_s ではなく、この POSIX の strtok_r の定義に一致します。
[編集] 例
このコードを実行
#define __STDC_WANT_LIB_EXT1__ 1 #include <stdio.h> #include <string.h> int main(void) { char input[] = "A bird came down the walk"; printf("Parsing the input string '%s'\n", input); char* token = strtok(input, " "); while (token) { puts(token); token = strtok(NULL, " "); } printf("Contents of the input string now: '"); for (size_t n = 0; n < sizeof input; ++n) input[n] ? putchar(input[n]) : fputs("\\0", stdout); puts("'"); #ifdef __STDC_LIB_EXT1__ char str[] = "A bird came down the walk"; rsize_t strmax = sizeof str; const char* delim = " "; char* next_token; printf("Parsing the input string '%s'\n", str); token = strtok_s(str, &strmax, delim, &next_token); while (token) { puts(token); token = strtok_s(NULL, &strmax, delim, &next_token); } printf("Contents of the input string now: '"); for (size_t n = 0; n < sizeof str; ++n) str[n] ? putchar(str[n]) : fputs("\\0", stdout); puts("'"); #endif }
実行結果の例
Parsing the input string 'A bird came down the walk' A bird came down the walk Contents of the input string now: 'A\0bird\0came\0down\0the\0walk\0' Parsing the input string 'A bird came down the walk' A bird came down the walk Contents of the input string now: 'A\0bird\0came\0down\0the\0walk\0'
[編集] 参照
- C23標準 (ISO/IEC 9899:2024)
- 7.24.5.8 strtok 関数 (p: TBD)
- K.3.7.3.1 strtok_s 関数 (p: TBD)
- C17標準 (ISO/IEC 9899:2018)
- 7.24.5.8 strtok 関数 (p: TBD)
- K.3.7.3.1 strtok_s 関数 (p: TBD)
- C11標準 (ISO/IEC 9899:2011)
- 7.24.5.8 strtok 関数 (p: 369-370)
- K.3.7.3.1 strtok_s 関数 (p: 620-621)
- C99標準 (ISO/IEC 9899:1999)
- 7.21.5.8 strtok 関数 (p: 332-333)
- C89/C90標準 (ISO/IEC 9899:1990)
- 4.11.5.8 strtok 関数
[編集] 関連項目
| ある文字列に含まれる任意の文字が、別の文字列で最初に出現する位置を見つける (関数) | |
| 以下から成る最大の初期セグメントの長さを返す 別のバイト文字列に含まれない文字のみ (関数) | |
| 以下から成る最大の初期セグメントの長さを返す 別のバイト文字列に含まれる文字のみ (関数) | |
| (C95)(C11) |
ワイド文字列内の次のトークンを見つける (関数) |
| C++ ドキュメント (strtok)
| |