web-dev-qa-db-fra.com

strtok () - Pourquoi vous devez passer le pointeur NULL pour obtenir le prochain jeton dans la chaîne?

C'est l'explication de strtok ().

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

Le premier appel à strtok () renvoie un pointeur sur le premier jeton de la chaîne pointée par s1. Les appels suivants à strtok () doivent passer un pointeur NULL comme premier argument, afin d'obtenir le prochain jeton dans la chaîne.

Mais je ne sais pas, pourquoi vous devez passer le pointeur NULL pour obtenir le prochain jeton dans la chaîne. J'ai cherché environ 15 minutes, mais je n'ai pas trouvé d'explication sur Internet.

22
phez1

strtok() conserve certaines données à l'intérieur d'elle-même en utilisant des variables statiques. De cette façon, strtok() peut continuer la recherche à partir du point où elle s'était arrêtée lors de l'appel précédent. Pour signaler à strtok() que vous souhaitez continuer à rechercher la même chaîne, vous passez un pointeur NULL comme premier argument. strtok() vérifie si le premier argument est NULL et s'il l'est, il utilise ses données actuellement stockées. Si le premier paramètre n'est pas nul, il est traité comme une nouvelle recherche et toutes les données internes sont réinitialisées.

Peut-être que la meilleure chose à faire est de rechercher une implémentation réelle de la fonction strtok(). J'en ai trouvé un assez petit pour le poster ici, donc vous avez une idée de la façon de gérer ce paramètre 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

Si vous passez une valeur non NULL, vous lui demandez de commencer à tokeniser une chaîne différente.

Si vous transmettez une valeur NULL, vous demandez à continuer de symboliser la même chose qu'auparavant.

12
StilesCrisis