嵌套while循环中的strtok意外行为

0 c strtok

我有一个看起来像1,3-5,7,9-11的字符串,我要通过重复调用strtok来标记它,以便输出看起来像:

1
3
5
7
9
11
Run Code Online (Sandbox Code Playgroud)

我的代码看起来像这样:

#include <stdio.h>
#include <string.h>

void tokenize(char *string){
    char *token;
    token = strtok (string,"-");
    while (token != NULL) {
            // ... do some other unrelated stuff ...
            printf("\tToken %s\n", token);
            token = strtok (NULL, ",");
    }
}

int main (int argc,char **argv)
{
    char *token;
    token = strtok (*(argv+1),",");
    while (token != NULL) {
            if (strchr(token,45)){  //45 is ASCII for "-".
                    tokenize(token);
            }
            printf("Token1 %s \n", token);
            token = strtok (NULL, ",");
    }
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

但是,当我运行代码时它会提前结束,我得到:

./tokenizer 1,3-5,7,9-11
Token1 1
        Token 3
        Token 5
Token1 3
Run Code Online (Sandbox Code Playgroud)

但我希望/想要这样的东西:

./tokenizer 1,3-5,7,9-11
Token1 1
        Token 3
        Token 5
Token1 7
        Token 9
        Token 11
Run Code Online (Sandbox Code Playgroud)

如果我注释掉读取的行tokenize(temptoken);(换句话说,strtok on","),那么输出看起来就像人们期望的那样:

./tokenizer 1,3-5,7,9-11
Token1 1
Token1 3-5
Token1 7
Token1 9-11
Run Code Online (Sandbox Code Playgroud)

因此看起来问题确实是随后对已经标记化的字符串的strtok调用所以我试图将memcpy内存指向为令牌指针,但这并没有真正帮助:

#include <stdio.h>
#include <string.h>

void tokenize(char *string){
    char *token;
    token = strtok (string,"-");
    while (token != NULL) {

            printf("\tToken %s\n", token);
            token = strtok (NULL, ",");
    }
}

int main (int argc,char **argv)
{
    char *token;
    char *temptoken ;
    token = strtok (*(argv+1),",");
    while (token != NULL) {
            if (strchr(token,45)){  //45 is ASCII for "-".
/* added memcpy */  memcpy(temptoken,token,strlen(token)+1);
                    tokenize(temptoken);
            }
            printf("Token1 %s \n", token);
            token = strtok (NULL, ",");
    }
    return 0;
} 


$ ./tokenizer 1,3-5,7,9-11 
Token1 1
        Token 3
        Token 5
Token1 3-5
Run Code Online (Sandbox Code Playgroud)

我可以做些什么来修复代码,了解我的误解所在,并获得所需的输出?

Jes*_*man 5

您不能使用嵌套,strtok()因为它使用一些静态内存来保存调用之间的上下文,以了解被标记化的字符串中的当前位置.

strtok_r()相反,使用strtok的可重入版本,它没有任何内部状态.