【问题标题】:C: correct usage of strtok_rC: strtok_r的正确使用
【发布时间】:2013-04-04 09:13:18
【问题描述】:

如何使用 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

【问题讨论】:

标签: c char strtok


【解决方案1】:
char str[]="string for sample";
char *reserve;
char *pchE = strtok_r(str, " ", &reserve);//when next call str -> NULL

【讨论】:

    【解决方案2】:

    strtok_r 的documentation 很清楚。

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

    【讨论】:

      【解决方案3】:

      测试示例:

      #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 documentation,我的重点是:

      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() 调用序列同时解析不同的字符串。

      【讨论】:

        【解决方案4】:

        我发布了一个经过测试的示例,以了解 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
        是的
        o

        现在让我们在同一个例子中使用 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
        是的
        o
        u
        a.r.e
        一个
        r
        电子
        呵呵
        h
        电子
        r
        电子

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

        【讨论】:

          猜你喜欢
          • 2020-05-19
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2011-10-23
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多