strtok - ライブラリコールの説明 - Linux コマンド集 一覧表
名前
strtok, strtok_r - 文字列からトークンを取り出す
書式
#include <string.h>
char *strtok(char *str, const char *delim);
char *strtok_r(char *str, const char *delim, char **saveptr);
説明
strtok
() 関数は文字列を解析してトークンに分割する。
strtok
() を最初に呼び出す際には、解析対象の文字列を str
に
指定する。同じ文字列の解析を行うその後の呼び出しでは、
str
には NULL を指定する。
delim
引き数には、解析する文字列をトークンに区切る文字集合を
指定する。同じ文字列を解析する一連の呼び出しにおいて、
delim
に違う文字列を指定してもよい。
strtok
() のそれぞれの呼び出しでは、次のトークンを
格納した NULL 終端された文字列へのポインタが返される。
この文字列には区切り文字は含まれない。
これ以上トークンが見つからなかった場合には、NULL が返される。
解析対象の文字列に2つ以上の区切り文字が連続している場合には、
一つの区切り文字とみなされる。
文字列の先頭や末尾にある区切り文字は無視される。言い換えると、
strtok
() が返すトークンは常に空でない文字列となる。
strtok_r
()関数は
strtok
()のリエントラント版である。
saveptr
引き数は char *
変数へのポインタであり、
同じ文字列の解析を行う
strtok_r
()の呼び出し間で処理状況を保存するために
strtok_r
()内部で使用される。
strtok_r
()を最初に呼び出す際には、
str
は解析対象の文字列を指していなければならず、
saveptr
の値は無視される。それ以降の呼び出しでは、
str
は NULL とし、
saveptr
は前回の呼び出し以降変更しないようにしなければならない。
strtok_r
()の呼び出し時に異なる saveptr
引き数を指定することで、
異なる文字列の解析を同時に行うことができる。
例
以下のプログラムは、 strtok_r ()を利用するループを入れ子にして使用し、 文字列を2階層のトークンに分割するものである。 1番目のコマンドライン引き数には、解析対象の文字列を指定する。 2番目の引き数には、文字列を「大きな」トークンに分割するために 使用する区切り文字を指定する。 3番目の引き数には、「大きな」トークンを細かく分割するために 使用する区切り文字を指定する。
#include <stdio.h> #include <stdlib.h> #include <string.h>
int main(int argc, char *argv[]) { char *str1, *str2, *token, *subtoken; char *saveptr1, *saveptr2; int j;
if (argc != 4) { fprintf(stderr, "Usage: %s string delim subdelim\n", argv[0]); exit(EXIT_FAILURE); }
for (j = 1, str1 = argv[1]; ; j++, str1 = NULL) { token = strtok_r(str1, argv[2], &saveptr1); if (token == NULL) break; printf("%d: %s", j, token);
for (str2 = token; ; str2 = NULL) { subtoken = strtok_r(str2, argv[3], &saveptr2); if (subtoken == NULL) break; printf(" --> %s", subtoken); } }
exit(EXIT_SUCCESS); } /* main */
このプログラムの出力例を以下に示す。
$ ./a.out 'a/bbb///cc;xxx:yyy:' ':;' '/' 1: a/bbb///cc --> a --> bbb --> cc 2: xxx --> xxx 3: yyy --> yyy
バグ
これらの関数は絶対に使用しないこと。 使用する場合は、以下の点に注意すること。
これらの関数はその最初の引数を変更する。
これらの関数は const な文字列では使えない。
区切り文字自体は失われてしまう。
strtok
()関数は文字列の解析に静的バッファを用いるので、スレッドセーフでない。
これが問題になる場合は
strtok_r
()を用いること。
返り値
strtok () と strtok_r () は次のトークンへのポインタか、 トークンがなければ NULL を返す。
準拠
- strtok ()
- SVr4, POSIX.1-2001, 4.3BSD, C89.
- strtok_r ()
- POSIX.1-2001