この関数の目的
strtok()は、文字列を単位(トークン)に分ける。
定義
#include <string.h> char *strtok(char *s1, const char *s2);
働き
連続してこの関数を呼ぶと、 s1 が指す文字列は、 s2 が指す文字列中の文字で区切られる、トークンの連なりに分割される。 連なりでの最初の呼び出しで s1 を第一引数にとり、次回以降の呼び出しは第一引数にヌルポインタをとる。 s2 が指す分割文字列は呼出しごとに異なっても良い。
連なりの最初の呼び出しで、 s1 が指す文字列の中から s2 が指す分割文字列に含まれない最初の文字を探す。 発見されなかった場合は、 s1 にはトークンは入らず、関数はヌルポインタを返す。 発見された場合は、それが最初のトークンの始まりとなる。
次に、この関数はそこから分割文字列に含まれる文字を探す。 文字が見つからなかった場合、現在のトークンは s1 が指す文字列の終端まで伸び、続けてトークンを探すとヌルポインタが返る。 文字が見つかった場合、その文字はヌル文字で上書きされ、トークンはそこで終わる。 この関数は次の文字へのポインタを保持し、次のトークンを探しはじめる場所とする。
続けてヌルポインタを第一引数に渡して呼ぶごとに、保持されたポインタから検索を始め、上述のような動作をする。
処理系は、一度も strtok() を呼ばないかのように動作しなければならない。
返り値は、トークンの最初の文字へのポインタか、トークンが無ければヌルポインタである。
解説
トークン(token)というのは構文解析プログラムで使われる用語で、解析された単位を言う。 「英単語」に近い意味合いである。
簡単に言うと、 s2 に含まれる文字で s1 を分割し、分割された部分文字列を呼ぶごとに返す関数である。 分割する際、 s1 に与えられた文字列をヌル文字で切り刻むので、オリジナルが必要なら、コピーをとる必要がある。
関数の使い方は、例を見るのが一番分かりやすい。
#include <stdio.h> #include <string.h> void main(void){ char str[] = "str == NULL ? \"(NULL)\" : str"; char *p; p = strtok(str, "?:"); while(p) { printf("|%s|\n", p); p = strtok(NULL, "?:"); } } /* 出力例: |str == NULL | | "(NULL)" | | str| */
すでに述べたように、この例で出力が終わった後の配列 str
の内容は "str == NULL \0 \"(NULL)\" \0 str"
というふうになる。
このように strtok 関数は第一引数の指すオブジェクトを書き換えるので(宣言を見ても const 修飾子がついていない)、
getenv 関数の返り値のような、プログラム内で共有するオブジェクトに使うときには注意が必要である。