strtok
のC
とstrtok_r
の違いは何ですか?いつどちらを使用することになっていますか?
strtok
は次と同等です(多くの場合、次のように定義されます)。
char *strtok(char *str, const char *delim) {
static char *save;
return strtok_r(str, delim, &save);
}
一般に、コードをstrtok
のみをサポートするPOSIX-2001より前のシステムに移植可能にする必要がない限り、strtok
ではなくstrtok_r
を直接使用する必要があります。
関数の__r
_バージョンは再入可能です。複数のスレッドから同時に呼び出すことも、ネストされたループなどで呼び出すこともできます。再入可能なバージョンは通常、追加の引数を取ります。この引数は、グローバル変数を使用する代わりに、呼び出し間の状態を格納するために使用されます。
非再入可能バージョンはグローバル状態を使用することが多いため、複数のスレッドから呼び出す場合は、おそらく未定義の動作を呼び出しています。プログラムがクラッシュする可能性があります。
マニュアルページから(_man 3 strtok
_):
strtok_r()
関数は、strtok()
の再入可能なバージョンです。最後のコンテキストポインタは、各呼び出しで提供する必要があります。strtok_r()
関数は、別々のコンテキストポインターが使用されている限り、2つの解析ループを相互にネストするためにも使用できます。
strtok
は、最初のパラメーターとしてNULLを指定したときに、次回再利用するために静的ポインターを保存するため、2つの文字列を並行して解析することはできません。
の中に strtok_r
outパラメーター(ポインターへのポインター)として、ポインターも指定します。したがって、関数には静的ポインタがなく、ある文字列から別の文字列に移動したり、戻ったりすることができます。
ドキュメントによると、strtok_r()関数はstrtok()の再入可能なバージョンです。
char *strtok_r(char *s1, const char *s2, char **s3);
文字列s1から次のトークンを取得します。トークンはs2の文字で区切られた文字列です。 s1から最初のトークンを取得するために、strtok_r()がs1を最初のパラメーターとして呼び出されます。 s1の残りのトークンは、最初のパラメーターにnullポインターを指定してstrtok_r()を呼び出すことによって取得されます。区切り文字の文字列s2は、呼び出しごとに異なる場合があります。