40

我怎样才能使用 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

4

4 回答 4

48

strtok_r的文档非常清楚。

strtok_r() 函数是一个可重入版本的 strtok()。saveptr 参数是一个指向 char * 变量的指针,strtok_r() 内部使用该变量来维护解析相同字符串的连续调用之间的上下文。

在第一次调用 strtok_r() 时,str 应该指向要解析的字符串,并且忽略 saveptr 的值。在随后的调用中,str 应为 NULL,并且 saveptr 应自上次调用以来未更改。

所以你会有这样的代码

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

foo = strtok_r(str, " ", &saveptr);
bar = strtok_r(NULL, " ", &saveptr);
于 2013-04-12T00:47:16.473 回答
20

测试示例:

#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 应该自上次调用以来保持不变

可以使用指定不同 saveptr 参数的 strtok_r() 调用序列同时解析不同的字符串。

于 2015-01-09T12:48:36.900 回答
8

我发布了一个经过测试的示例,以了解 strtok_r() 的正确用法,而不是在嵌套中使用 strtok()。

首先让我们取一个字符串“you,are,here”并使用分隔符“,”和“。”分隔。

使用 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;
}

输出:




_

现在让我们使用 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;
}

输出:

你 你 在
这儿
_ _ _ _ _ _ _ _ _










因此 strtok_r() 具有可重入属性,而 strtok() 不具有那样的功能。

于 2019-05-11T08:20:49.407 回答
1
char str[]="string for sample";
char *reserve;
char *pchE = strtok_r(str, " ", &reserve);//when next call str -> NULL
于 2013-04-12T00:46:23.437 回答