Namespaces
Variants

strtok, strtok_s

From cppreference.net
< c ‎ | string ‎ | byte
ヘッダーで定義 <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 が非NULLの場合、この呼び出しは一連の呼び出しにおける 最初の呼び出し となる。検索対象は str が指すNULL終端バイト文字列である。
  • str がNULLの場合、この呼び出しは一連の呼び出しにおける 後続の呼び出し の一つとなる。検索対象はシーケンス内の前回の呼び出しによって決定される。
シーケンス内の各呼び出しは、検索対象から delim が指す セパレータ文字列 含まれない 最初の文字を検索します。セパレータ文字列は呼び出しごとに異なっていても構いません。
  • そのような文字が見つからない場合、検索対象にはトークンが存在しません。シーケンス内の次の呼び出しにおける検索対象は変更されません。 [1]
  • そのような文字が見つかった場合、それが現在のトークンの開始位置となります。 strtok はその後、セパレータ文字列に含まれる最初の文字を検索します。
    • そのような文字が見つからない場合、現在のトークンは検索対象の終端まで延長されます。シーケンス内の次の呼び出しにおける検索対象は空文字列になります。 [2]
    • そのような文字が見つかった場合、その文字はヌル文字で上書きされ、これにより現在のトークンが終了します。シーケンス内の次の呼び出しにおける検索対象は次の文字から開始されます。
str または delim がnull終端バイト文字列へのポインタでない場合、動作は未定義です。
2) 以下を除き (1) と同じ:
  • 各呼び出しで、 str 内に残っている文字数を * strmax に書き込み、トークナイザの内部状態を * ptr に書き込む。
  • シーケンス内の後続の呼び出しでは、前回の呼び出しで保存された値を持つ strmax ptr を渡さなければならない。
  • 以下のエラーは実行時に検出され、 ptr が指すオブジェクトに何も保存せずに、現在インストールされている 制約ハンドラ 関数を呼び出す:
    • strmax delim 、または ptr がヌルポインタである。
    • シーケンス内の後続の呼び出しで * ptr がヌルポインタである。
    • * strmax RSIZE_MAX より大きい。
    • 検出されたトークンの終端が、検索対象の先頭 * s1max 文字内に存在しない。
str がヌル文字を欠く文字配列を指し、かつ strmax がその文字配列のサイズより大きい値を指す場合、動作は未定義です。
すべての境界チェック付き関数と同様に、 strtok_s は、 __STDC_LIB_EXT1__ が実装によって定義され、かつユーザーが __STDC_WANT_LIB_EXT1__ を整数定数 1 に定義した場合にのみ利用可能であることが保証されます( <string.h> をインクルードする前)。
  1. 異なる区切り文字列を用いた後続の呼び出しでトークンが形成される可能性があります。
  2. 後続の呼び出しではこれ以上トークンを形成できません。

目次

パラメータ

str - トークン化するNULL終端バイト文字列へのポインタ
delim - 区切り文字を識別するNULL終端バイト文字列へのポインタ
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)
ワイド文字列内の次のトークンを検索する
(関数)