C:strtok_r函数的正确使用方法

43

我应该如何使用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?


请查看此链接:https://dev59.com/G3E95IYBdhLWcg3wn_Zr - Grijesh Chauhan
4个回答

53

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

25

测试的例子:

#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()时,str应指向要解析的字符串,忽略saveptr的值。在后续调用中,str应为NULL,并且saveptr应该与前一次调用保持不变。
可以使用一系列对strtok_r()的调用并指定不同的saveptr参数来同时解析不同的字符串。

9

我会给你提供一个经过测试的示例,以便更好地理解在嵌套中使用strtok_r()的正确用法,而不是使用strtok()。

首先,我们来取一个字符串"y.o.u,a.r.e,h.e.r.e"并使用定界符","和"."进行分离。

使用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.o.u
y
o
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.o.u
y
o
u
a.r.e
a
r
e
h.e.r.e
h
e
r
e

因此,strtok_r()具有可重入特性,而strtok()不具备此功能。


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

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接