Подтвердить что ты не робот

Strtok() - Почему вам нужно передать указатель NULL, чтобы получить следующий токен в строке?

Это объяснение strtok().

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

Первый вызов strtok() возвращает указатель на первый токен в строка, на которую указывает s1. Последующие вызовы strtok() должны пройти NULL указатель как первый аргумент, чтобы получить следующий токен в строка.

Но я не знаю, почему вам нужно передать указатель NULL, чтобы получить следующий токен в строке. Я искал около 15 минут, но не нашел объяснений в Интернете.

4b9b3361

Ответ 1

strtok() хранит некоторые данные в статических переменных внутри самой функции, поэтому может продолжить поиск с той точки, в которой он оставил предыдущий вызов. Чтобы сигнализировать strtok(), что вы хотите продолжать поиск в той же строке, вы передаете указатель NULL в качестве своего первого аргумента. strtok() проверяет, является ли это 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;
}

Ответ 2

Если вы передаете значение, отличное от NULL, вы просите его начать токенизацию другой строки.

Если вы передадите значение NULL, вы просите продолжить токенизацию того же самого, что и раньше.