Veuillez m'expliquer le fonctionnement de la strtok()
fonction. Le manuel dit qu'il divise la chaîne en jetons. Je suis incapable de comprendre à partir du manuel ce qu'il fait réellement.
J'ai ajouté des montres str
et *pch
pour vérifier son fonctionnement lorsque la première boucle while s'est produite, le contenu de str
n'était que "ceci". Comment la sortie ci-dessous s'est-elle imprimée à l'écran?
/* strtok example */
#include <stdio.h>
#include <string.h>
int main ()
{
char str[] ="- This, a sample string.";
char * pch;
printf ("Splitting string \"%s\" into tokens:\n",str);
pch = strtok (str," ,.-");
while (pch != NULL)
{
printf ("%s\n",pch);
pch = strtok (NULL, " ,.-");
}
return 0;
}
Production:
Splitting string "- Ceci, un exemple de chaîne." en jetons: Ce une échantillon chaîne
strtok()
modifie sa chaîne d'arguments en terminant les jetons avec NUL avant de retourner. Si vous essayez d'examiner tout le tampon (str []), vous verrez qu'il est modifié entre les appels successifs àstrtok()
.str
, regarderstr[0]
,str[1]
,str[2]
, ...Réponses:
strtok()
divise la chaîne en jetons. c'est-à-dire à partir de l'un quelconque des délimiteurs au suivant serait votre seul jeton. Dans votre cas, le jeton de départ sera de "-" et se terminera par l'espace suivant "". Ensuite, le jeton suivant commencera par "" et se terminera par ",". Ici, vous obtenez "This" en sortie. De même, le reste de la chaîne est divisé en jetons d'espace en espace et termine finalement le dernier jeton sur "."la source
la fonction d'exécution strtok fonctionne comme ceci
la première fois que vous appelez strtok, vous fournissez une chaîne que vous souhaitez tokenize
dans l'espace de chaîne ci-dessus semble être un bon délimiteur entre les mots, alors utilisons cela:
ce qui se passe maintenant est que 's' est recherché jusqu'à ce que le caractère d'espace soit trouvé, le premier jeton est retourné ('this') et p pointe vers ce jeton (chaîne)
afin d'obtenir le jeton suivant et de continuer avec la même chaîne, NULL est passé comme premier argument puisque strtok maintient un pointeur statique vers votre chaîne passée précédemment:
p pointe maintenant vers 'est'
et ainsi de suite jusqu'à ce qu'il n'y ait plus d'espaces, alors la dernière chaîne est renvoyée comme dernier jeton «chaîne».
plus commodément, vous pouvez l'écrire comme ceci à la place pour imprimer tous les jetons:
ÉDITER:
Si vous voulez stocker les valeurs renvoyées,
strtok
vous devez copier le jeton dans un autre tampon, par exemplestrdup(p);
puisque la chaîne d'origine (pointée par le pointeur statique à l'intérieurstrtok
) est modifiée entre les itérations afin de renvoyer le jeton.la source
p
pointe vers ce jeton» , est qu'ilstrtok
faut muter la chaîne d'origine en plaçant un caractère nul à la place d'un délimiteur (sinon les autres fonctions de chaîne ne sauraient pas où le jeton se termine). Et il garde également une trace de l'état à l'aide d'une variable statique.strtok
conserve une référence interne statique pointant vers le prochain jeton disponible dans la chaîne; si vous lui passez un pointeur NULL, il fonctionnera à partir de cette référence interne.C'est la raison
strtok
pour laquelle il n'est pas ré-entrant; dès que vous lui passez un nouveau pointeur, cette ancienne référence interne est écrasée.la source
strtok
ne change pas le paramètre lui-même (str
). Il stocke ce pointeur (dans une variable statique locale). Il peut ensuite modifier ce vers quoi ce paramètre pointe dans les appels suivants sans que le paramètre ne soit renvoyé. (Et il peut avancer ce pointeur qu'il a conservé comme il en a besoin pour effectuer ses opérations.)Depuis la
strtok
page POSIX :Il existe une variante thread-safe (
strtok_r
) qui ne fait pas ce type de magie.la source
ctime
renvoyer une chaîne statique - pratique (personne n'a besoin de se demander qui devrait la libérer), mais pas rentrante et vous trébuche si vous n'êtes pas très conscient de cela.strtok
ne change pas le paramètre lui-même (str
)."puts(str);
imprime "- Ceci"strtok
modifié depuisstr
.La première fois que vous l'appelez, vous fournissez la chaîne de tokenize
strtok
. Et puis, pour obtenir les jetons suivants, il vous suffit de donnerNULL
à cette fonction, tant qu'elle renvoie un nonNULL
pointeur.La
strtok
fonction enregistre la chaîne que vous avez fournie pour la première fois lorsque vous l'appelez. (Ce qui est vraiment dangereux pour les applications multi-thread)la source
strtok va tokeniser une chaîne c'est à dire la convertir en une série de sous-chaînes.
Il le fait en recherchant des délimiteurs qui séparent ces jetons (ou sous-chaînes). Et vous spécifiez les délimiteurs. Dans votre cas, vous voulez "" ou "," ou "." ou «-» pour être le délimiteur.
Le modèle de programmation pour extraire ces jetons est que vous remettez strtok votre chaîne principale et l'ensemble des délimiteurs. Ensuite, vous l'appelez à plusieurs reprises, et chaque fois que strtok retournera le prochain jeton qu'il trouve. Jusqu'à ce qu'il atteigne la fin de la chaîne principale, lorsqu'il renvoie un null. Une autre règle est que vous ne transmettez la chaîne que la première fois et NULL pour les fois suivantes. C'est un moyen d'indiquer à strtok si vous démarrez une nouvelle session de tokenisation avec une nouvelle chaîne ou si vous récupérez des jetons d'une session de tokenisation précédente. Notez que strtok se souvient de son état pour la session de création de jetons. Et pour cette raison, il n'est pas réentrant ou thread-safe (vous devriez utiliser strtok_r à la place). Une autre chose à savoir est qu'il modifie en fait la chaîne d'origine. Il écrit '\ 0' pour les délimiteurs qu'il trouve.
Une façon d'appeler strtok, succinctement, est la suivante:
Résultat:
la source
strtok modifie sa chaîne d'entrée. Il y place des caractères nuls ('\ 0') afin de renvoyer des bits de la chaîne d'origine sous forme de jetons. En fait, strtok n'alloue pas de mémoire. Vous comprendrez peut-être mieux si vous dessinez la chaîne sous la forme d'une séquence de cases.
la source
Pour comprendre comment
strtok()
fonctionne, il faut d'abord savoir ce qu'est une variable statique . Ce lien l' explique assez bien ...La clé du fonctionnement de
strtok()
est de conserver l'emplacement du dernier séparateur entre les appels secondaires (c'est pourquoistrtok()
continue d'analyser la chaîne très originale qui lui est transmise lorsqu'elle est invoquée avec unnull pointer
appel successif).Jetez un œil à ma propre
strtok()
implémentation, appeléezStrtok()
, qui a une fonctionnalité légèrement différente de celle fournie parstrtok()
Et voici un exemple d'utilisation
Le code provient d' une bibliothèque de traitement de chaînes que je gère sur Github , appelée zString. Jetez un œil au code, ou même contribuez :) https://github.com/fnoyanisi/zString
la source
C'est ainsi que j'ai implémenté strtok, pas si génial mais après avoir travaillé 2 heures dessus, il a finalement fonctionné. Il prend en charge plusieurs délimiteurs.
la source
strtok remplace les caractères du deuxième argument par un NULL et un caractère NULL est également la fin d'une chaîne.
http://www.cplusplus.com/reference/clibrary/cstring/strtok/
la source
Voici mon implémentation qui utilise une table de hachage pour le délimiteur, ce qui signifie qu'il O (n) au lieu de O (n ^ 2) (voici un lien vers le code) :
la source
strtok () stocke le pointeur dans une variable statique à l'endroit où vous l'avez laissé la dernière fois, donc lors de son deuxième appel, lorsque nous passons la valeur null, strtok () obtient le pointeur de la variable statique.
Si vous fournissez le même nom de chaîne, il recommence à partir du début.
De plus strtok () est destructif, c'est-à-dire qu'il modifie la chaîne de caractères d'origine. alors assurez-vous d'avoir toujours une copie de l'original.
Un autre problème de l'utilisation de strtok () est que comme il stocke l'adresse dans des variables statiques, dans la programmation multithread, appeler strtok () plus d'une fois provoquera une erreur. Pour cela, utilisez strtok_r ().
la source
Pour ceux qui ont encore du mal à comprendre cette
strtok()
fonction, jetez un œil à cet exemple de pythontutor , c'est un excellent outil pour visualiser votre code C (ou C ++, Python ...).Au cas où le lien serait rompu, collez:
Les crédits vont à Anders K.
la source
vous pouvez scanner le tableau de caractères à la recherche du jeton si vous l'avez trouvé, imprimez simplement une nouvelle ligne sinon imprimez le caractère.
la source
Donc, ceci est un extrait de code pour aider à mieux comprendre ce sujet.
Jetons d'impression
Tâche: À partir d'une phrase, imprimez chaque mot de la phrase sur une nouvelle ligne.
Contribution:
How is that
Résultat:
Explication: Ici, la fonction "strtok ()" est utilisée et elle est itérée en utilisant la boucle for pour imprimer les jetons sur des lignes séparées.
La fonction prendra des paramètres comme «chaîne» et «point de rupture» et coupera la chaîne à ces points de rupture et formera des jetons. Désormais, ces jetons sont stockés dans «p» et sont ensuite utilisés pour l'impression.
la source