strtok, strtok_s
提供: cppreference.com
<tbody>
</tbody>
<tbody class="t-dcl-rev t-dcl-rev-num ">
</tbody><tbody>
</tbody>
| ヘッダ <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)
str の指すヌル終端バイト文字列内の次のトークンを探します。 区切り文字は delim の指すヌル終端バイト文字列によって表されます。 この関数は同じ文字列から連続するトークンを取得するために複数回呼ばれるように設計されています。
str != NULLの場合、その呼び出しはこの特定の文字列に対するstrtokの初回の呼び出しとして扱われます。delimに含まれない最初の文字を検索します。
- そのような文字が見つからなかった場合、
strにはトークンがまったくなく、ヌルポインタが返されます。 - そのような文字が見つかった場合、それは「トークンの開始位置」です。 その位置から
delimに含まれる最初の文字を検索します。
- そのような文字が見つからなかった場合、
strはトークンを1個だけ持ち、strtokの以後の呼び出しはヌルポインタを返します。 - そのような文字が見つかった場合、それはヌル文字
'\0'で置き換えられ、その次の文字を指すポインタが2回目以降の呼び出しのために静的な場所に格納されます。
- そのような文字が見つからなかった場合、
- その後、トークンの開始位置を指すポインタが返されます。
- そのような文字が見つからなかった場合、
str == NULLの場合、その呼び出しはstrtokの2回目以降の呼び出しとして扱われます。 この関数は前回の呼び出しの残りの場所から続きを行います。 前回格納されたポインタがstrに渡されたかのように動作します。
str または delim がヌル終端バイト文字列を指すポインタでない場合、動作は未定義です。2) (1) と同じですが、ステップごとに
str 内の残りの文字数を *strmax に書き込み、トークナイザの内部状態を *ptr に書き込みます。 繰り返しの呼び出し (str がヌル) は前回の呼び出しで格納された値を持つ strmax および ptr を渡さなければなりません。 また、以下のエラーが実行時に検出され、 ptr の指すオブジェクトに何も格納せずに現在設定されている制約ハンドラ関数を呼びます。
strmax、delimまたはptrがヌルポインタ。- 2回目以降の呼び出し (
strがヌル) で、*ptrがヌルポインタ。 - 初回の呼び出しで、
*strmaxがゼロまたは RSIZE_MAX より大きい。 - トークンの終端の検索がヌル終端に遭遇せずにソース文字列の終端 (
*strmaxの初期値によって表される) に達した。
str がヌル文字のない文字配列を指し、 strmax がその文字配列のサイズより大きい値を指す場合、動作は未定義です。
- すべての境界チェック付き関数と同様に、
strtok_sは__STDC_LIB_EXT1__が処理系によって定義されていて、<string.h>をインクルードする前にユーザが__STDC_WANT_LIB_EXT1__を整数定数 1 に定義した場合にのみ、利用可能であることが保証されます。
引数
| str | - | トークン化するヌル終端バイト文字列を指すポインタ |
| delim | - | 区切り文字を表すヌル終端バイト文字列を指すポインタ |
| strmax | - | 初期状態で str のサイズを保持するオブジェクトを指すポインタ。 strtok_s が調べる残りの文字数を格納します
|
| ptr | - | strtok_s が内部状態を格納するために使用する char* 型のオブジェクトを指すポインタ
|
戻り値
次のトークンの開始位置を指すポインタ、またはこれ以上トークンがない場合は NULL を返します。
ノート
この関数は破壊的です。 文字列 str の要素に '\0' 文字を書き込みます。 特に、文字列リテラルを strtok の第1引数として使用することはできません。
strtok は呼ぶたびに静的変数を変更します。 スレッドセーフではありません。
他のほとんどのトークナイザと異なり、 strtok の区切り文字はトークンごとに異なってもよく、前のトークンの内容に依存することもできます。
strtok_s 関数は POSIX の strtok_r 関数と異なり、トークン化する文字列の外側に格納しないよう保護し、実行時制約をチェックします。
例
Run this code
#define __STDC_WANT_LIB_EXT1__ 1
#include <string.h>
#include <stdio.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'
参考文献
- C11 standard (ISO/IEC 9899:2011):
- 7.24.5.8 The strtok function (p: 369-370)
- K.3.7.3.1 The strtok_s function (p: 620-621)
- C99 standard (ISO/IEC 9899:1999):
- 7.21.5.8 The strtok function (p: 332-333)
- C89/C90 standard (ISO/IEC 9899:1990):
- 4.11.5.8 The strtok function
関連項目
| 文字列中の任意の文字が別の文字列中に現れる最初の位置を探します (関数) | |
| 別のバイト文字列に含まれない文字のみで構成され最も長い先頭部分の長さを返します (関数) | |
| 別のバイト文字列に含まれる文字のみで構成される最も長い先頭部分の長さを返します (関数) | |
(C95)(C11) |
ワイド文字列から次のトークンを探します (関数) |
strtok の C++リファレンス
| |