strtokによるトークンの切り出し
はじめに
strtok()
は与えられた文字列を指定した区切り文字で区切り、トークンを返す関数である。トークンとは最小単位の文字列を意味しており、例えば英語の文章を空白区切りでトークンを切り出す場合、個々のトークンが単語を表している。ここではstrtok()
の詳細を見ていく。
strtok()
strtok
は文字列と区切り文字を引数にとりトークンの先頭へのポインタを返す。
#include <string.h>
char *strtok(char *str, const char *delim);
ここでポイントになるのは
- 第一引数の文字列は書き換えられる。具体的には見つけた区切り文字が
\0
に置換されていく。 - 最終的に返しているのは置換した'\0' を末尾とする文字列の先頭へのポインタ
- 2回目以降 はNULL を引数に呼び出す。これはstrtok の関数内でどこまで切りだしたかが記憶されていることによる(static 変数として記録されている)
である。
例
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main(){
char *a = "abc def ghi jkl";
// 破壊されるのでコピーする
char buf[20];
strcpy(buf, a);
// 最初にbuf がどうなっているのか整数でみてみる
for (int i = 0 ; i < 20 ; i++){
printf("%d\n", buf[i]);
}
// この時点での
printf("%p\n", buf);
// 初回呼び出しで区切りたい文字列を指定
char *p;
p = strtok(buf, " ");
printf("%p: %s\n", p, p); // bufの先頭と一致する
// 2回目以降はbufで最初に見つけた区切り文字のあとの有効文字列に
// 関数内部でポインタが当たっており、NULL を指定することで
// そこから読み出すことを関数に伝えている
while ( (p = strtok(NULL, " ")) != NULL ){
printf("%p: %s\n", p, p);
}
// 最後にbuf がどうなっているのか整数でみてみる
for (int i = 0 ; i < 20 ; i++){
printf("%d\n", buf[i]);
}
return 0;
}
上記の実行例より、strtokが区切り文字を見つけると\0
で置換し、文字列として終端させるが、NULLを引数とすることでその先を引き続き読み出している ことが読み取れる。