web-dev-qa-db-ja.com

Cのstrtokとstrtok_rの違いは何ですか?

strtokCstrtok_rの違いは何ですか?いつどちらを使用することになっていますか?

14
dreamer_999

strtokは次と同等です(多くの場合、次のように定義されます)。

char *strtok(char *str, const char *delim) {
    static char *save;
    return strtok_r(str, delim, &save);
}

一般に、コードをstrtokのみをサポートするPOSIX-2001より前のシステムに移植可能にする必要がない限り、strtokではなくstrtok_rを直接使用する必要があります。

18
Chris Dodd

関数の__r_バージョンは再入可能です。複数のスレッドから同時に呼び出すことも、ネストされたループなどで呼び出すこともできます。再入可能なバージョンは通常、追加の引数を取ります。この引数は、グローバル変数を使用する代わりに、呼び出し間の状態を格納するために使用されます。

非再入可能バージョンはグローバル状態を使用することが多いため、複数のスレッドから呼び出す場合は、おそらく未定義の動作を呼び出しています。プログラムがクラッシュする可能性があります。

マニュアルページから(_man 3 strtok_):

strtok_r()関数は、strtok()の再入可能なバージョンです。最後のコンテキストポインタは、各呼び出しで提供する必要があります。 strtok_r()関数は、別々のコンテキストポインターが使用されている限り、2つの解析ループを相互にネストするためにも使用できます。

14
Dietrich Epp

strtokは、最初のパラメーターとしてNULLを指定したときに、次回再利用するために静的ポインターを保存するため、2つの文字列を並行して解析することはできません。

の中に strtok_r outパラメーター(ポインターへのポインター)として、ポインターも指定します。したがって、関数には静的ポインタがなく、ある文字列から別の文字列に移動したり、戻ったりすることができます。

5
SHR

ドキュメントによると、strtok_r()関数はstrtok()の再入可能なバージョンです。

char *strtok_r(char *s1, const char *s2, char **s3);

文字列s1から次のトークンを取得します。トークンはs2の文字で区切られた文字列です。 s1から最初のトークンを取得するために、strtok_r()がs1を最初のパラメーターとして呼び出されます。 s1の残りのトークンは、最初のパラメーターにnullポインターを指定してstrtok_r()を呼び出すことによって取得されます。区切り文字の文字列s2は、呼び出しごとに異なる場合があります。

0
Miguel Prz