首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >嵌套而循环中的strtok行为出乎意料。

嵌套而循环中的strtok行为出乎意料。
EN

Stack Overflow用户
提问于 2017-07-13 15:09:21
回答 2查看 675关注 0票数 0

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

代码语言:javascript
运行
复制
1
3
5
7
9
11

我的代码如下所示:

代码语言:javascript
运行
复制
#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;
}

但是,当我运行代码时,它过早地结束,我得到:

代码语言:javascript
运行
复制
./tokenizer 1,3-5,7,9-11
Token1 1
        Token 3
        Token 5
Token1 3

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

代码语言:javascript
运行
复制
./tokenizer 1,3-5,7,9-11
Token1 1
        Token 3
        Token 5
Token1 7
        Token 9
        Token 11

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

代码语言:javascript
运行
复制
./tokenizer 1,3-5,7,9-11
Token1 1
Token1 3-5
Token1 7
Token1 9-11

因此,看起来问题确实在于随后对已标记字符串的strtok调用,因此我尝试将memcpy内存指向标记指针,但这并没有真正帮助:

代码语言:javascript
运行
复制
#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

对于我能做些什么来修复代码,理解我的误解所在,并得到想要的输出,有什么想法吗?

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2017-07-13 15:18:06

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

而是使用strtok_r(),它是一个不具有任何内部状态的strtok的可重入版本。

票数 5
EN

Stack Overflow用户

发布于 2017-07-13 15:21:28

代码语言:javascript
运行
复制
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, ",");
}

你还指望什么。

您正在查找令牌',‘,然后使用您的函数对其进行标记化(并打印令牌),然后在子标记化之前再次打印该令牌,当strtok具有内部状态时,它将结束。

所以它和你写的一模一样。

你需要:使用可重入的版本

您应该返回tokenize函数中的值,以指示是否找到了子令牌:如果没有打印令牌,如果没有打印,则不要打印。

票数 -1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/45084674

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档