127 votes

Comment strtok() divise-t-il la chaîne de caractères en tokens en C ?

Veuillez m'expliquer le fonctionnement de strtok() fonction. Le manuel indique qu'elle décompose la chaîne de caractères en jetons. Je ne parviens pas à comprendre ce qu'elle fait réellement.

J'ai ajouté des montres sur str et *pch pour vérifier son fonctionnement lors de la première boucle while, le contenu du fichier str étaient seulement "ceci". Comment la sortie montrée 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;
}

Sortie :

Splitting string "- This, a sample string." into tokens:
This
a
sample
string

2voto

KingKohn Points 93

Voici mon implémentation qui utilise une table de hachage pour le délimiteur, ce qui signifie que c'est O(n) au lieu de O(n^2) (voici un lien vers le code) :

#include<stdio.h>
#include<stdlib.h>
#include<string.h>

#define DICT_LEN 256

int *create_delim_dict(char *delim)
{
    int *d = (int*)malloc(sizeof(int)*DICT_LEN);
    memset((void*)d, 0, sizeof(int)*DICT_LEN);

    int i;
    for(i=0; i< strlen(delim); i++) {
        d[delim[i]] = 1;
    }
    return d;
}

char *my_strtok(char *str, char *delim)
{

    static char *last, *to_free;
    int *deli_dict = create_delim_dict(delim);

    if(!deli_dict) {
        /*this check if we allocate and fail the second time with entering this function */
        if(to_free) {
            free(to_free);
        }
        return NULL;
    }

    if(str) {
        last = (char*)malloc(strlen(str)+1);
        if(!last) {
            free(deli_dict);
            return NULL;
        }
        to_free = last;
        strcpy(last, str);
    }

    while(deli_dict[*last] && *last != '\0') {
        last++;
    }
    str = last;
    if(*last == '\0') {
        free(deli_dict);
        free(to_free);
        deli_dict = NULL;
        to_free = NULL;
        return NULL;
    }
    while (*last != '\0' && !deli_dict[*last]) {
        last++;
    }

    *last = '\0';
    last++;

    free(deli_dict);
    return str;
}

int main()
{
    char * str = "- This, a sample string.";
    char *del = " ,.-";
    char *s = my_strtok(str, del);
    while(s) {
        printf("%s\n", s);
        s = my_strtok(NULL, del);
    }
    return 0;
}

1voto

Patrick Points 3893

Strtok remplace les caractères du second 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/

1voto

Vaibhav Points 131

Strtok() stocke le pointeur dans la variable statique où vous vous êtes arrêté la dernière fois, donc à son 2ème appel, lorsque nous passons le null, strtok() récupère le pointeur de la variable statique.

Si vous fournissez le même nom de chaîne, il recommence depuis le début.

De plus, strtok() est destructif, c'est-à-dire qu'il modifie la chaîne originale. Assurez-vous donc d'avoir toujours une copie de la chaîne originale.

Un autre problème lié à l'utilisation de strtok() est que, comme il stocke l'adresse dans des variables statiques, dans une programmation multithread, appeler strtok() plus d'une fois provoquera une erreur. Pour cela, utilisez strtok_r().

0voto

Fahad Alotaibi Points 368

Vous pouvez parcourir le tableau de chars à la recherche du jeton si vous le trouvez, imprimez une nouvelle ligne sinon, imprimez le char.

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

int main()
{
    char *s;
    s = malloc(1024 * sizeof(char));
    scanf("%[^\n]", s);
    s = realloc(s, strlen(s) + 1);
    int len = strlen(s);
    char delim =' ';
    for(int i = 0; i < len; i++) {
        if(s[i] == delim) {
            printf("\n");
        }
        else {
            printf("%c", s[i]);
        }
    }
    free(s);
    return 0;
}

0voto

tr_abhishek Points 17

Voici donc un extrait de code qui vous aidera à mieux comprendre ce sujet.

Impression de jetons

Tâche : Étant donné une phrase, s, imprimez chaque mot de la phrase sur une nouvelle ligne.

char *s;
s = malloc(1024 * sizeof(char));
scanf("%[^\n]", s);
s = realloc(s, strlen(s) + 1);
//logic to print the tokens of the sentence.
for (char *p = strtok(s," "); p != NULL; p = strtok(NULL, " "))
{
    printf("%s\n",p);
}

Entrée : How is that

Résultat :

How
is
that

Explication : Donc ici, la fonction "strtok()" est utilisée et elle est itérée en utilisant la boucle for pour imprimer les jetons dans des lignes séparées.

La fonction prend les paramètres 'string' et 'break-point' et casse la chaîne à ces points de rupture et forme des jetons. Ces jetons sont ensuite stockés dans 'p' et sont utilisés pour l'impression.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X