web-dev-qa-db-fra.com

C: utilisation correcte de strtok_r

Comment puis-je utiliser strtok_r au lieu de strtok pour ce faire?

char *pchE = strtok(NULL, " ");

Maintenant, j'essaie d'utiliser strtok_r correctement ... Mais parfois j'ai des problèmes avec le strtol. J'ai un thread que j'exécute 10 fois (en même temps).

char *savedEndd1;
char *nomeClass = strtok_r(lineClasses, " ", &savedEndd1);
char *readLessonS = strtok_r (NULL, " ", &savedEndd1);
char *readNTurma = strtok_r(NULL, " ",  &savedEndd1);

if (readNTurma==NULL)
printf("CLASS STRTOL begin %s %s\n",nomeClass, readLessonS );
int numberNTurma = strtol(readNTurma, NULL, 10);

Et j'attrape ça readNTurma == NULL plusieurs fois ... Pourquoi ça? Vous ne comprenez pas pourquoi cela vient NULL?

36
Carlcox89

Le documentation pour strtok_r est assez clair.

La fonction strtok_r () est une version réentrante strtok (). L'argument saveptr est un pointeur vers une variable char * qui est utilisée en interne par strtok_r () afin de maintenir le contexte entre les appels successifs qui analysent la même chaîne.

Lors du premier appel à strtok_r (), str doit pointer vers la chaîne à analyser et la valeur de saveptr est ignorée. Dans les appels suivants, str doit être NULL et saveptr doit être inchangé depuis l'appel précédent.

Vous auriez donc du code comme

char str[] = "Hello world";
char *saveptr;
char *foo, *bar;

foo = strtok_r(str, " ", &saveptr);
bar = strtok_r(NULL, " ", &saveptr);
39
tangrs

Exemple testé:

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

int main(void)
{
    char str[] = "1,22,333,4444,55555";
    char *rest = NULL;
    char *token;

    for (token = strtok_r(str, ",", &rest);
         token != NULL;
         token = strtok_r(NULL, ",", &rest)) {   
        printf("token:%s\n", token);
    }

    return 0;
}

Résultat.

token:1
token:22
token:333
token:4444
token:55555

Test: http://codepad.org/6xRdIecI

De documentation linux où l'accent est le mien:

char *strtok_r(char *str, const char *delim, char **saveptr);

La fonction strtok_r () est une version réentrante strtok (). L'argument saveptr est un pointeur sur une variable char * qui est utilisée en interne par strtok_r () afin de maintenir le contexte entre les appels successifs qui analysent la même chaîne .

Lors du premier appel à strtok_r () , str doit pointer vers la chaîne à analyser et la valeur de saveptr est ignoré. Dans les appels suivants, str doit être NULL et saveptr doit être inchangé depuis l'appel précédent .

Différentes chaînes peuvent être analysées simultanément en utilisant des séquences d'appels à strtok_r () qui spécifient différents arguments saveptr.

13
MrHIDEn

Je poste un exemple testé pour comprendre l'utilisation correcte de strtok_r () au lieu d'utiliser strtok () dans les nids.

permet d'abord de prendre une chaîne "y.o.u, a.r.e, h.e.r.e" et de séparer en utilisant les délimiteurs "," et "."

en utilisant strtok ()

#include<stdio.h>
#include<string.h>
int main(void) {

        char str[]="y.o.u,a.r.e,h.e.r.e";
        const char *p=",", *q=".";
        char *a,*b;

        for( a=strtok(str,p) ; a!=NULL ; a=strtok(NULL,p) ) {
                printf("%s\n",a);
                for( b=strtok(a,q) ; b!=NULL ; b=strtok(NULL,q) )
                        printf("%s\n",b);
        }

        return 0;
}

SORTIE:

toi
y
o
u

permet maintenant d'utiliser strtok_r () pour le même exemple

en utilisant strtok_r ()

#include<stdio.h>
#include<string.h>
int main(void) {

        char str[]="y.o.u,a.r.e,h.e.r.e";
        const char *p=",",*q=".";
        char *a,*b,*c,*d;

        for( a=strtok_r(str,p,&c) ; a!=NULL ; a=strtok_r(NULL,p,&c) ) {
                printf("%s\n",a);

                for( b=strtok_r(a,q,&d) ; b!=NULL ; b=strtok_r(NULL,q,&d) )
                        printf("%s\n",b);
        }

        return 0;
}

SORTIE:

toi
y
o
u
sont
une
r
e
ici
h
e
r
e

donc strtok_r () a une propriété réentrante alors que strtok () ne fonctionne pas comme ça.

1
char str[]="string for sample";
char *reserve;
char *pchE = strtok_r(str, " ", &reserve);//when next call str -> NULL
1
BLUEPIXY