web-dev-qa-db-ja.com

strtok()-文字列内の次のトークンを取得するためにNULLポインターを渡す必要があるのはなぜですか?

これがstrtok()の説明です。

#include <string.h>
char* strtok( char* s1, 
              const char* s2 );*

Strtok()の最初の呼び出しは、s1が指すストリング内の最初のトークンへのポインターを返します。 strtok()への後続の呼び出しは、文字列内の次のトークンを取得するために、最初の引数としてNULLポインターを渡す必要があります。

しかし、文字列内の次のトークンを取得するためにNULLポインターを渡す必要がある理由はわかりません。 15分ほど検索しましたが、インターネットで説明が見つかりませんでした。

22
phez1

strtok()は、静的変数を使用して、内部にデータを保持します。このようにして、strtok()は前回の呼び出し中に中断したポイントから検索を続行できます。同じ文字列を検索し続けることをstrtok()に通知するには、最初の引数としてNULLポインタを渡します。 strtok()は、最初の引数がNULLであるかどうかをチェックし、そうである場合、現在保存されているデータを使用します。最初のパラメーターがnullでない場合、新しい検索として扱われ、すべての内部データがリセットされます。

おそらくあなたができる最善のことは、strtok()関数の実際の実装を検索することです。ここに投稿するのに十分小さいものを見つけたので、このNULLパラメータを処理する方法のアイデアを得ることができます。

/* Copyright (c) Microsoft Corporation. All rights reserved. */

#include <string.h>

/* ISO/IEC 9899 7.11.5.8 strtok. DEPRECATED.
 * Split string into tokens, and return one at a time while retaining state
 * internally.
 *
 * WARNING: Only one set of state is held and this means that the
 * WARNING: function is not thread-safe nor safe for multiple uses within
 * WARNING: one thread.
 *
 * NOTE: No library may call this function.
 */

char * __cdecl strtok(char *s1, const char *delimit)
{
    static char *lastToken = NULL; /* UNSAFE SHARED STATE! */
    char *tmp;

    /* Skip leading delimiters if new string. */
    if ( s1 == NULL ) {
        s1 = lastToken;
        if (s1 == NULL)         /* End of story? */
            return NULL;
    } else {
        s1 += strspn(s1, delimit);
    }

    /* Find end of segment */
    tmp = strpbrk(s1, delimit);
    if (tmp) {
        /* Found another delimiter, split string and save state. */
        *tmp = '\0';
        lastToken = tmp + 1;
    } else {
        /* Last segment, remember that. */
        lastToken = NULL;
    }

    return s1;
}
39
mcleod_ideafix

NULL以外の値を渡すと、別の文字列のトークン化を開始するように求めています。

NULL値を渡すと、以前と同じもののトークン化を続行するように求められます。

12
StilesCrisis