strtok() question: Si les jetons sont délimités par des séparateurs,pourquoi est le dernier jeton entre le séparateur et le nul '\0'?
Dans le programme suivant, strtok()
fonctionne comme prévu dans la majeure partie, mais je ne peux pas comprendre la raison derrière une conclusion. J'ai lu sur strtok()
que:
Pour déterminer le début et la fin d'un jeton, la fonction première des analyses à partir de l'emplacement de départ pour le premier caractère ne figurant pas dans les délimiteurs (qui devient le début du jeton). Et puis les scans à partir de ce début de jeton pour le premier caractère figurant dans les séparateurs, qui devient à la fin du jeton.
Et comme nous le savons, strtok()
place un \0
à la fin de chaque jeton. Mais dans le programme suivant, le dernier, le séparateur est un point(.
), après quoi il est Crapaud entre ce point et le guillemet ("
). Maintenant que le point est un délimiteur dans mon programme, mais il n'y a pas de délimiteur après Crapaud, même pas un espace blanc (qui est un délimiteur dans mon programme). Veuillez effacer la confusion suivante découlant de cette prémisse:
Pourquoi est strtok()
considérant Crapaud, à titre symbolique, même si elle n'est pas entre les 2 séparateurs? C'est ce que j'ai lu sur strtok()
lorsqu'il rencontre un caractère NULL (\0
):
Une fois le caractère de fin null de str a été trouvé dans un appel à strtok, tous les appels à cette fonction avec un pointeur null en tant que premier argument retourner un pointeur null.
Nulle part il n'est dit qu'une fois un caractère nul est rencontré,un pointeur vers le début de l'jeton est renvoyé (nous n'avons même pas un jeton d'ici tant que nous n'avons pas eu une fin de le jeton comme il n'y a pas de délimiteur de caractère après le scan commencé depuis le début du jeton (c'est à dire de " T " de Crapaud), nous n'avons trouvé qu'un caractère null, pas un délimiteur). Alors pourquoi est le partie entre le dernier délimiteur et le guillemet de la chaîne d'argument considéré comme un jeton par strtok()
? Veuillez expliquer cela.
Code:
#include <stdio.h>
#include <string.h>
int main ()
{
char str[] =" Falcon,eagle-hawk..;buzzard,gull..pigeon sparrow,hen;owl.Toad";
char * pch=strtok(str," ;,.-");
while (pch != NULL)
{
printf ("%s\n",pch);
pch = strtok (NULL, " ;,.-");
}
return 0;
}
De sortie:
Falcon
aigle
hawk
buse
mouette
pigeon
moineau
poule
chouette
Crapaud
- Pas sûr de comprendre votre question; quelle sortie vous attendiez-vous? Que
Toad
ne serait pas être imprimé? En passant par cette logique, si vous retirez de l'espace dans la chaîne d'entrée,Falcon
ne devrait pas être imprimés. Je dirais que le fait pour certains des comportements non-intuitifs. - Si vous avez supprimé le vide avant de le Faucon,
strtok()
serait encore envisager de "Faucon", pour être le premier jeton. - J'ai délibérément fait.Comme je l'ai dit ,tout est comme prévu à partir de
strtok()
,sauf le dernier jeton,qui n'est clairement pas entre les deux délimiteurs. - Je regrette de l'avoir eu à aller à l'extérieur juste après l'affichage de cette question.
- Pourquoi ne devrais-je pas attendre la
Falcon
à imprimer?Je l'ai mentionné à partir de la source quethe function first scans from the starting location for the first character not contained in delimiters
..c'est à dire,pour le début de l'jeton nous n'avons pas besoin d'un séparateur(espace est un délimiteur dans mon programme),mais pour marquer la fin du jeton, nous avons clairement besoin un délimiteur,et NULLE en fin de chaîne n'est pas sur la liste délimiteur. - Je suis surpris, je ne pouvais pas transmettre mon point de même pour vous à cette question.
Vous devez vous connecter pour publier un commentaire.
De la norme de spécification de
strtok
(7.24.5.8) est assez clair. En particulier, le paragraphe 4 (italiques ajoutés par moi) est directement pertinente pour la question, si je comprends bien:Dans un appel
le jeton (un pointeur vers ce qui est) retourné - le cas échéant - s'étend de la première non-caractère délimiteur trouvé à partir de la position de départ (inclus) jusqu'à la prochaine caractère délimiteur (exclusif), s'il existe, ou à la fin de la chaîne, si pas plus tard caractère délimiteur existe.
Liés description n'est pas explicitement mentionner le cas d'un jeton se prolongeant jusqu'à la fin de la chaîne, contrairement à la norme, elle est donc incomplète à cet égard.
If no such character is found, the current token extends to the end of the string pointed to by s1, and subsequent searches for a token will return a null pointer
---Je vous remercie,que des clous,prendre à droite à partir de la norme.C'est exactement ce que je voulais savoir.Va à la description dans POSIX pour
strtok()
, la description dit:Note de la deuxième phrase du troisième paragraphe:
Cela indique clairement que, dans l'exemple en question,
Toad
est en effet un jeton. Une façon de penser, c'est que la liste des délimiteurs comprend toujours NUL'\0'
à la fin de la chaîne de séparation.Avoir un diagnostic qui, à noter que
strtok()
n'est pas une bonne fonction à utiliser — il n'est pas thread-safe ou rentrante. Sur Windows, vous pouvez utiliserstrtok_s()
à la place; sur Unix, vous pouvez généralement utiliserstrtok_r()
. Ces fonctions sont mieux parce qu'ils ne pas stocker en interne, le pointeur au cours de laquelle la recherche est à reprendre.Parce que
strtok()
n'est pas réentrant, vous ne pouvez pas appeler une fonction qui utilisestrtok()
à partir de l'intérieur d'une fonction que lui-même utilisestrtok()
alors que c'est à l'aide destrtok()
. Aussi, toute fonction de bibliothèque qui utilisestrtok()
doit être clairement identifiée comme telle parce qu'elle ne peut être appelée depuis une fonction à l'aide destrtok()
. Ainsi, l'utilisation destrtok()
rend la vie difficile.L'autre problème avec la
strtok()
famille de fonctions (et avecstrsep()
, qui est lié), c'est qu'ils remplacer le séparateur; vous ne pouvez pas savoir ce que le séparateur est après le tokenizer a segmenté la chaîne. Cela peut, dans certaines applications (telles que l'analyse de shell de ligne de commande; il la question de savoir si le délimiteur est un tuyau ou un point-virgule ou une esperluette (ou ...). Ainsi, shell analyseurs habitude de ne pas utiliserstrtok()
, malgré le nombre de questions sur DONC sur des coquilles d'où l'analyseur n'utilisezstrtok()
.En général, vous devriez orienter clairement de la plaine
strtok()
, et c'est à vous de décider sistrtok_r()
oustrtok_s()
est approprié pour vos besoins.Parce que cplusplus.com n'est-ce pas vous raconter toute l'histoire. Cppreference.com a une meilleure description.
Cplusplus.com aussi, il oublie de mentionner que
strtok
n'est pas thread-safe, et seuls les documents de lastrtok
de la fonction du langage de programmation C++, alors que cppreference.com ne mentionne pas le fil d'un problème de sécurité et documents de lastrtok
les fonctions des deux C et la C++ langages de programmation.Vous êtes peut-être juste mal la lecture de la description?
Donné "ultérieure", je suis en train de lire ce que chaque appel à
strtok
après celui qui a découvert\0
, pas nécessairement le cours lui-même. Ainsi, la définition est cohérente avec le comportement (et de ce que vous attendez destrtok
).And then scans starting from this beginning of the token for the first character contained in delimiters, which becomes the end of the token.
strtok
en soi.strtok
est erronée, même par un glissement de la langue!!De toute façon,vous vous êtes proche de ce que j'ai l'intention de demander....Voir,à la fin de l'avant-dernier jeton,le pointeur pointe versT
deToad
,mais pour marquer la fin du jeton, il a besoin d'un délimiteur.Mais il n'y a pas de délimiteur après et le caractère null est rencontré,au point où il s'arrête.Alors comment est-ce Crapaud un jeton?strtok pauses d'une chaîne à une séquence de tokens, séparés par les délimiteurs.
Les délimiteurs des jetons, pas forcément d'y mettre fin sur les deux côtés.