読者です 読者をやめる 読者になる 読者になる

Bye Bye Moore

猫マンション建築の野望を胸に零細事業主として資本主義の荒波に漕ぎ出したアラサー男の技術メモ

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言語全体がそんな感じですが