Подтвердить что ты не робот

C: правильное использование strtok_r

Как я могу использовать strtok_r вместо strtok для этого?

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

Теперь я пытаюсь использовать strtok_r правильно... Но иногда я получаю проблемы с strtol. У меня есть поток, который я выполняю 10 раз (в то же время).

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);

И я несколько раз ловил это readNTurma == NULL... Почему? Не могу понять, почему он приходит NULL?

4b9b3361

Ответ 1

документация для strtok_r довольно ясна.

Функция strtok_r() является реентерабельной версией strtok(). Аргумент saveptr является указателем на переменную char *, которая внутренне используется strtok_r(), чтобы поддерживать контекст между последовательными вызовами, которые анализируют одну и ту же строку.

При первом вызове strtok_r() str должен указывать на строку, которая должна быть проанализирована, а значение savept игнорируется. В последующих вызовах str должна быть NULL, а saveptr не должен меняться со времени предыдущего вызова.

Итак, у вас будет код вроде

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

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

Ответ 2

Протестированный пример:

#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;
}

Результат.

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

Тест: http://codepad.org/6xRdIecI

Из документации Linux, где акцент мой

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

Функция strtok_r() является реентерабельной версией strtok(). Аргумент saveptr - это указатель на переменную char *, которая внутренне используется strtok_r() для поддержания контекста между последовательными вызовами, которые анализируют одну и ту же строку.

При первом вызове strtok_r() str должен указывать на строку, которую нужно проанализировать, а значение saveptr игнорируется. В последующих вызовах str должен быть NULL, а saveptr не должен изменяться с момента предыдущего вызова.

Разные строки могут быть проанализированы одновременно, используя последовательности вызовов strtok_r(), которые определяют разные аргументы saveptr.

Ответ 3

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

Ответ 4

Я опубликую проверенный пример, чтобы понять правильное использование strtok_r() вместо использования strtok() в гнездах.

сначала давайте возьмем строку "ты, здесь" и разделим ее с помощью разделителей "," и "."

используя 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;
}

ВЫХОД:

вы
Y
о
U

теперь давайте используем strtok_r() для того же примера

используя 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;
}

ВЫХОД:

вы
Y
о
U
являются

р
е
Вот
час
е
р
е

следовательно, strtok_r() имеет свойство reentrant, тогда как strtok() не работает таким образом.