关于char:C:strtok_r的正确用法

C: correct usage of strtok_r

如何使用strtok_r而不是strtok来做到这一点?

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

现在我正在尝试正确使用strtok_r ...但是有时我会遇到strtol问题。
我有一个线程,我同时执行了10次。

1
2
3
4
5
6
7
8
9
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\
"
,nomeClass, readLessonS );
int numberNTurma = strtol(readNTurma, NULL, 10);

我几次抓到那个readNTurma == NULL ...为什么呢?无法理解为什么会出现NULL


strtok_r的文档非常清楚。

The strtok_r() function is a reentrant version strtok(). The saveptr argument is a pointer to a char * variable that is used internally by strtok_r() in order to maintain context between successive calls that parse the same string.

On the first call to strtok_r(), str should point to the string to be parsed, and the value of saveptr is ignored. In subsequent calls, str should be NULL, and saveptr should be unchanged since the previous call.

因此您将拥有类似

的代码

1
2
3
4
5
6
char str[] ="Hello world";
char *saveptr;
char *foo, *bar;

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


测试示例:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
#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\
"
, token);
    }

    return 0;
}

结果。

1
2
3
4
5
token:1
token:22
token:333
token:4444
token:55555

测试:http://codepad.org/6xRdIecI

摘自linux文档,重点是我的:

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

The strtok_r() function is a reentrant version strtok(). The saveptr argument is a pointer to a char * variable that is used internally by strtok_r() in order to maintain context between successive calls that parse the same string.

On the first call to strtok_r(), str should point to the string to be parsed, and the value of saveptr is ignored. In subsequent calls, str should be NULL, and saveptr should be unchanged since the previous call.

Different strings may be parsed concurrently using sequences of calls to strtok_r() that specify different saveptr arguments.


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

首先让我们接受一个字符串" y.o.u,a.r.e,h.e.r.e"
并使用定界符","和"。"分隔

using strtok()

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
#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\
"
,a);
                for( b=strtok(a,q) ; b!=NULL ; b=strtok(NULL,q) )
                        printf("%s\
"
,b);
        }

        return 0;
}

输出:

y.o.u
y
o
u

现在让我们使用strtok_r()进行相同的示例

using strtok_r()

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
#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\
"
,a);

                for( b=strtok_r(a,q,&d) ; b!=NULL ; b=strtok_r(NULL,q,&d) )
                        printf("%s\
"
,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
2
3
char str[]="string for sample";
char *reserve;
char *pchE = strtok_r(str,"", &reserve);//when next call str -> NULL