strtok, strtok_r - Extraire des séquences d'une chaîne
Bibliothèque C standard (
libc,
-lc)
#include <string.h>
char *strtok(char *restrict str, const char *restrict delim);
char *strtok_r(char *restrict str, const char *restrict delim,
char **restrict saveptr);
strtok_r() :
_POSIX_C_SOURCE
|| /* glibc <= 2.19 : */ _BSD_SOURCE || _SVID_SOURCE
La fonction
strtok() scinde une chaîne en une suite de zéro
ou plusieurs séquences non vides. Lors du premier appel à
strtok(), la chaîne à scinder doit être
spécifiée dans
str. Dans chaque appel ultérieur
fait pour analyser la même chaîne,
str doit être
NULL.
L'argument
delim indique l’ensemble des octets qui
délimitent les séquences dans la chaîne à
analyser. La chaîne de séparateurs
delim peut être
différente à chaque appel sur la même chaîne.
Chaque appel à
strtok() renvoie un pointeur sur une chaîne
terminée par un octet NULL contenant la séquence suivante. Cette
chaîne n'inclut pas le séparateur. S'il n'y a plus de
séquences,
strtok renvoie NULL.
Une suite d'appels à
strtok() qui s'exécute sur la
même chaîne gère un pointeur qui indique le point de
départ de la recherche pour la séquence suivante. Le premier
appel à
strtok() positionne ce pointeur sur le premier octet de
la chaîne. Le début de la séquence suivante est
déterminé en parcourant
str jusqu'à l'octet
suivant qui ne soit pas un séparateur. Lorsqu'un tel octet est
rencontré, il est pris comme point de départ de la
séquence suivante. Si aucun octet n’est trouvé qui ne
soit pas un séparateur, alors il n'y a plus de séquence dans la
chaîne et
strtok() renvoie NULL. (Ainsi, pour une chaîne
vide ou qui ne contient que des séparateurs,
strtok() renverra
NULL dès le premier appel).
La fin de chaque séquence est déterminée en parcourant la
chaîne jusqu'à ce que l'octet suivant soit un délimiteur,
ou jusqu'à ce qu'on rencontre l'octet NULL final
(« \0 »). Si un délimiteur est
trouvé, il est écrasé par un octet NULL pour signifier la
fin de la séquence en cours de détermination, et
strtok()
positionne un pointeur sur l'octet suivant ; ce pointeur marque le
point de départ de la recherche de la séquence suivante. Dans ce
cas,
strtok() renvoie un pointeur vers le début de la
séquence qui vient d'être isolée.
De ce qui précède, il découle qu'une suite de deux
séparateurs contigus ou plus est considérée comme un seul
séparateur et que les séparateurs en début et en fin de
chaîne sont ignorés. Les séquences renvoyées par
strtok() sont toujours des chaînes non vides. Si l'on
considère par exemple la chaîne «
aaa;;bbb,», les appels successifs à
strtok() pour
lequel le séparateur serait «
;,» renverraient les
chaînes «
aaa» et «
bbb», puis
un pointeur NULL.
La fonction
strtok_r() est la version réentrante de la fonction
strtok(). L'argument
saveptr est un pointeur sur une variable
char * utilisée de manière interne par
strtok_r() afin de maintenir le contexte entre les appels successifs
qui analysent la même chaîne.
Au premier appel de
strtok_r(),
str doit pointer sur la
chaîne à analyser et la valeur de
*saveptr est
ignorée (mais consultez les NOTES). Dans les appels suivants,
str doit être NULL et
saveptr (et le tampon vers lequel
il pointe) ne doit pas être modifié depuis le
précédent appel.
Différentes chaînes peuvent être analysées de
manière concurrente en utilisant des suites d'appels à
strtok_r() qui spécifient différents arguments
saveptr.
Les fonctions
strtok() et
strtok_r() renvoient un pointeur sur la
séquence suivante, ou NULL s'il n'y en a plus.
Pour une explication des termes utilisés dans cette section, consulter
attributes(7).
Interface |
Attribut |
Valeur |
strtok() |
Sécurité des threads |
MT-Unsafe race:strtok |
strtok_r() |
Sécurité des threads |
MT-Safe |
-
strtok()
- POSIX.1-2001, POSIX.1-2008, C99, SVr4, 4.3BSD.
-
strtok_r()
- POSIX.1-2001, POSIX.1-2008.
Pour plusieurs implémentations,
*saveptr doit être NULL
lors du premier appel à
strtok_r() utilisé pour analyser
str.
Faites attention quand vous utilisez ces fonctions. Si vous les utilisez, prenez
note des informations suivantes :
- •
- Ces fonctions modifient leur premier paramètre.
- •
- Ces fonctions ne peuvent pas être utilisées
avec des chaînes constantes.
- •
- L'identité du délimiteur est perdue.
- •
- La fonction strtok() utilise un tampon statique et
n'est donc pas sûre dans un contexte multithread. Dans ce cas, il
vaut mieux utiliser strtok_r().
Le programme ci-dessous utilise des boucles imbriquées qui utilisent
strtok_r() pour scinder une chaîne en une hiérarchie de
séquences à deux niveaux. Le premier argument de la ligne de
commande indique la chaîne à analyser. Le second argument
indique le ou les séparateurs utilisés pour séparer la
chaîne en séquences « majeures ». Le
troisième argument indique le ou les séparateurs utilisés
pour séparer les séquences
« majeures » en sous-séquences.
Voici un exemple de la sortie produite par ce programme :
$ ./a.out 'a/bbb///cc;xxx:yyy:' ':;' '/'
1: a/bbb///cc
--> a
--> bbb
--> cc
2: xxx
--> xxx
3: yyy
--> yyy
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int
main(int argc, char *argv[])
{
char *str1, *str2, *token, *subtoken;
char *saveptr1, *saveptr2;
int j;
if (argc != 4) {
fprintf(stderr, "Usage : %s string delim subdelim\n",
argv[0]);
exit(EXIT_FAILURE);
}
for (j = 1, str1 = argv[1]; ; j++, str1 = NULL) {
token = strtok_r(str1, argv[2], &saveptr1);
if (token == NULL)
break;
printf("%d: %s\n", j, token);
for (str2 = token; ; str2 = NULL) {
subtoken = strtok_r(str2, argv[3], &saveptr2);
if (subtoken == NULL)
break;
printf("\t --> %s\n", subtoken);
}
}
exit(EXIT_SUCCESS);
}
Un autre exemple de programme qui utilise
strtok() se trouve dans
getaddrinfo_a(3).
memchr(3),
strchr(3),
string(3),
strpbrk(3),
strsep(3),
strspn(3),
strstr(3),
wcstok(3)
La traduction française de cette page de manuel a été
créée par Christophe Blaess
<
https://www.blaess.fr/christophe/>, Stéphan Rafin
<
[email protected]>, Thierry Vignaud
<
[email protected]>, François Micaux, Alain Portal
<
[email protected]>, Jean-Philippe Guérard
<
[email protected]>, Jean-Luc Coulon (f5ibh)
<
[email protected]>, Julien Cristau
<
[email protected]>, Thomas Huriaux <
[email protected]>,
Nicolas François <
[email protected]>, Florentin
Duneau <
[email protected]>, Simon Paillard
<
[email protected]>, Denis Barbier
<
[email protected]>, David Prévot <
[email protected]>,
Frédéric Hantrais <
[email protected]> et Grégoire
Scano <
[email protected]>
Cette traduction est une documentation libre ; veuillez vous reporter
à la
GNU
General Public License version 3 concernant les conditions de copie
et de distribution. Il n'y a aucune RESPONSABILITÉ LÉGALE.
Si vous découvrez un bogue dans la traduction de cette page de manuel,
veuillez envoyer un message à
[email protected]