在C语言中嵌套循环中使用strtok()函数?

14

我试图在嵌套循环中使用 strtok() 函数,但这并没有给我期望的结果,可能是因为它们正在使用相同的内存位置。我的代码类似于:

char *token1 = strtok(Str1, "%");
while (token1 != NULL)
{
    char *token2 = strtok(Str2, "%");
    while (token2 != NULL)
    {
        //Do something
        token2 = strtok(NULL, "%");
    }
    // Do something more
    token1 = strtok(NULL, "%");
}

2
所以,现在你知道为什么人们会尽量避免使用strtok()了。因为它很难正确使用。 - Jonathan Leffler
3个回答

23

是的,strtok() 确实会在调用之间使用一些静态内存来保存上下文。请使用可重入版本的 strtok(),即 strtok_r(),或者如果您正在使用VS,则使用 strtok_s()(与 strtok_r() 相同)。

它有一个额外的上下文参数,您可以在不同的循环中使用不同的上下文。

char *tok, *saved;
for (tok = strtok_r(str, "%", &saved); tok; tok = strtok_r(NULL, "%", &saved))
{
    /* Do something with "tok" */
}

2
如果您没有编辑原因,解释为什么strtok会以这种方式运行,这里有关于strtok_r的更多信息:http://www.mkssoftware.com/docs/man3/strtok_r.3.asp - Welbog
有人能解释一下上面的循环是如何工作的吗? - MortalMan
@MortalMan:这个循环本身可以使用strtok()strtok_r()(或Microsoft的strtok_s())进行最小更改,以适应strtok()的不同调用约定。它只是在str中遍历标记。使用strtok_r()的不同之处在于,您还可以有一个内部循环也使用strtok_r()和一个不同的变量代替saved,而内部循环不会干扰外部循环。这是无法使用strtok()完成的。 - Jonathan Leffler

2

strtok使用静态缓冲区。 在您的情况下,您应该使用strtok_r。这个函数使用用户提供的缓冲区。


1

WayneAKing在Microsoft Developer Center中发布了一种替代方案

他引用道:

请前往此处

http://cpp.snippets.org/code/

并下载此文件

stptok.c 改进的分词函数

您还可以从同一网站下载所需的头文件。

这是strtok的修改版本,它将解析的标记(子字符串)放置在单独的缓冲区中。 您应该能够修改它以适应您的需求。

  • Wayne

P.S. - 请注意,这些文件可能采用*nix格式,关于行尾。 即-仅为0x0A而不是0x0D 0x0A

如果您的环境中没有 Microsoft 库,这是一种替代方案。


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