oracular (3) strtok_r.3.gz

Provided by: manpages-ja-dev_0.5.0.0.20221215+dfsg-1_all bug

名前

       strtok, strtok_r - 文字列からトークンを取り出す

書式

       #include <string.h>

       char *strtok(char *str, const char *delim);

       char *strtok_r(char *str, const char *delim, char **saveptr);

   glibc 向けの機能検査マクロの要件 (feature_test_macros(7)  参照):

       strtok_r(): _POSIX_C_SOURCE
           || /* Glibc versions <= 2.19: */ _BSD_SOURCE || _SVID_SOURCE

説明

       The  strtok()   function  breaks  a string into a sequence of zero or more nonempty tokens.  On the first
       call to strtok(), the string to be parsed should be specified in  str.   In  each  subsequent  call  that
       should parse the same string, str must be NULL.

       delim 引数には、解析対象の文字列をトークンに区切るのに使用する バイト集合を指定する。同じ文字列を解析する
       一連の呼び出しにおいて、 delim に違う文字列を指定してもよい。

       strtok()   のそれぞれの呼び出しでは、次のトークンを格納したヌル終端    された文字列へのポインターが返され
       る。この文字列には区切りバイトは含まれ   ない。これ以上トークンが見つからなかった場合には、NULL  が返され
       る。

       同じ文字列に対して操作を行う strtok() を連続して呼び出す場合、 次のトークンを探し始める位置を決めるための
       ポインターが保持される。  最初の strtok の呼び出しでは、 このポインターは対象の文字列の最初のバイトにセッ
       トされる。 次のトークンの先頭は、 str 内で次の区切りバイト以外のバイトを前方に検索して決定される。 区切り
       バイト以外のバイトが見つからなかった場合は、  トークンはこれ以上なく、  strtok() は NULL を返す (したがっ
       て、 空の文字列や区切りバイトだけを含む文字列の場合には、 最初の strtok() の呼び出しで NULL  が返ることに
       なる)。

       各トークンの末尾は、次の区切りバイトが見つかるか、終端のヌルバイト  ('\0') に達するまで文字列を前方に検索
       することで見つかる。 区切りバイトが見つかった場合には、 現在のトークンの終わりを示すために、 見つかった区
       切りバイトがヌルバイトで上書きされ、 strtok() はポインターを次のバイトに設定する。 このポインターは、次の
       トークンを検索する際の開始点として使用される。 この場合、  strtok()  は見つかったトークンの先頭へのポイン
       ターを返す。

       上記の説明の通り、 解析対象の文字列に 2 つ以上の区切りバイトが連続している場合には、 一つの区切りバイトと
       みなされ、 文字列の先頭や末尾にある区切りバイトは無視される。 言い換えると、 strtok()  が返すトークンは必
       ず空でない文字列となる。  したがって、例えば  "aaa;;bbb," という文字列が与えられたとすると、 区切り文字列
       ";," を指定した一連の strtok() の呼び出しでは、 "aaa" と bbb" が返り、その次にヌルポインターが返る。

       The strtok_r()  function is a reentrant version of strtok().  The saveptr argument  is  a  pointer  to  a
       char *  variable  that  is used internally by strtok_r()  in order to maintain context between successive
       calls that parse the same string.

       On the first call to strtok_r(), str should point to the string to be parsed, and the value  of  *saveptr
       is ignored (but see NOTES).  In subsequent calls, str should be NULL, and saveptr (and the buffer that it
       points to)  should be unchanged since the previous call.

       strtok_r()  の呼び出し時に異なる saveptr 引数を指定することで、  異なる文字列の解析を同時に行うことができ
       る。

返り値

       strtok()  と strtok_r()  は次のトークンへのポインターか、 トークンがなければ NULL を返す。

属性

       この節で使用されている用語の説明については、 attributes(7) を参照。

       ┌─────────────────┬───────────────┬───────────────────────┐
       │インターフェース属性                    │
       ├─────────────────┼───────────────┼───────────────────────┤
       │strtok()         │ Thread safety │ MT-Unsafe race:strtok │
       ├─────────────────┼───────────────┼───────────────────────┤
       │strtok_r()       │ Thread safety │ MT-Safe               │
       └─────────────────┴───────────────┴───────────────────────┘

準拠

       strtok()
              POSIX.1-2001, POSIX.1-2008, C89, C99, SVr4, 4.3BSD.

       strtok_r()
              POSIX.1-2001, POSIX.1-2008.

注意

       On  some  implementations, *saveptr is required to be NULL on the first call to strtok_r()  that is being
       used to parse str.

バグ

       これらの関数を使うのは慎重に吟味すること。 使用する場合は、以下の点に注意が必要である。

       * これらの関数はその最初の引数を変更する。

       * これらの関数は const な文字列では使えない。

       * 区切りバイト自体は失われてしまう。

       * strtok()  関数は文字列の解析に静的バッファーを用いるので、スレッドセーフでない。 これが問題になる場合は
         strtok_r() を用いること。

       以下のプログラムは、  strtok_r() を利用するループを入れ子にして使用し、 文字列を 2 階層のトークンに分割す
       るものである。 1番目のコマンドライン 引数には、解析対象の文字列を指定する。 2 番目の引数には、文字列を 「
       大きな」トークンに分割するために  使用する区切りバイトを指定する。 3 番目の引数には、「大きな」トークンを
       細かく分割するために使用する 区切りバイトを指定する。

       このプログラムの出力例を以下に示す。

           $ ./a.out 'a/bbb///cc;xxx:yyy:' ':;' '/'
           1: a/bbb///cc
                    --> a
                    --> bbb
                    --> cc
           2: xxx
                    --> xxx
           3: yyy
                    --> yyy

   プログラムのソース

       #include <stdio.h>
       #include <stdlib.h>
       #include <string.h>

       int
       main(int argc, char *argv[])
       {
           char *str1, *str2, *token, *subtoken;
           char *saveptr1, *saveptr2;

           if (argc != 4) {
               fprintf(stderr, "Usage: %s string delim subdelim\n",
                       argv[0]);
               exit(EXIT_FAILURE);
           }

           for (int j = 1, str1 = argv[1]; ; j++, str1 = NULL) {
               token = strtok_r(str1, argv[2], &saveptr1);
               if (token == NULL)
                   break;
               printf("%d: %s\n", j, token);

               for (str2 = token; ; str2 = NULL) {
                   subtoken = strtok_r(str2, argv[3], &saveptr2);
                   if (subtoken == NULL)
                       break;
                   printf(" --> %s\n", subtoken);
               }
           }

           exit(EXIT_SUCCESS);
       }

       strtok()  を使った別のプログラム例が getaddrinfo_a(3)  にある。

関連項目

       index(3), memchr(3),  rindex(3),  strchr(3),  string(3),  strpbrk(3),  strsep(3),  strspn(3),  strstr(3),
       wcstok(3)

この文書について

       この  man ページは Linux man-pages プロジェクトのリリース 5.10 の一部である。プロジェクトの説明とバグ報告
       に関する情報は https://www.kernel.org/doc/man-pages/ に書かれている。