Bye Bye Moore

PoCソルジャーな零細事業主が作業メモを残すブログ

strtokでchar配列を切り分ける

strtokはchar配列を特定のcharにて切り分ける関数です。
安全版のstrtok_rもあります。

感じとしてはRubyのsplitメソッドみたいです。
が、ちょいと癖があります。
Ruby風に言えば破壊的メソッドです。*1

挙動

初回

最初に対象となるchar配列と切り分け文字を指定します。
ここで指定した区切り文字をNULLにて置き換えます。
番兵法みたいですね。
以降、NULLの後ろにくっ付いたcharへのポインタ(トークン)を返して来ます。

二回目以降

配列を指定した部分にNULLを置きます。
エ、NULL!? NULLナンデ!?
NULLを指定しておけば、直前に使ったchar配列を呼び出してくれます。
言い方を変えれば、最初の引数に何かを設定した時点で内部のchar配列は初期化されます。

最後

全てが終わると、NULLを返して来ます。

より詳細な説明

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

strtok() 関数は文字列を 0 個以上の空でないトークンの列に分割する。 strtok() を最初に呼び出す際には、解析対象の文字列を str に 指定する。同じ文字列の解析を行うその後の呼び出しでは、 str は NULL にしなければならない。
delim 引き数には、解析対象の文字列をトークンに区切るのに使用する バイト集合を指定する。同じ文字列を解析する一連の呼び出しにおいて、 delim に違う文字列を指定してもよい。

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

引用もとより

実際の例

https://gist.github.com/shuzo-kino/7022015#file-test-strtok-c

上の例を実行すると

foo
bar
piyo

と出ます。

まとめ

便利ですが、実に挙動が奇妙なstrtok関数について見て来ました。
初回で指定、以降NULLなどとやっている辺り、再帰を意識した作りなのかもしれませんね。

*1:C言語全体がそんな感じですが