试图了解strtok

时间:2011-01-14 02:26:19

标签: c++ strtok

请考虑以下使用strtok拆分字符串madddy的代码段。

char* str = (char*) malloc(sizeof("Madddy"));
strcpy(str,"Madddy");

char* tmp = strtok(str,"d");
std::cout<<tmp;

do
{
    std::cout<<tmp;
    tmp=strtok(NULL, "dddy");
}while(tmp!=NULL);

工作正常,输出为Ma。但是通过将strtok修改为以下内容,

tmp=strtok(NULL, "ay");

输出变为Madd。那么strtok究竟是如何运作的呢?我有这个问题,因为我希望strtok将分隔符字符串中的每个字符作为分隔符。但在某些情况下,它是这样做的,但在少数情况下,它会产生意想不到的结果。谁能帮我理解这个?

6 个答案:

答案 0 :(得分:10)

“试图了解strtok”祝你好运!

无论如何,我们是在2011年。令人敬畏:

std::string str("abc:def");
char split_char = ':';
std::istringstream split(str);
std::vector<std::string> token;

for (std::string each; std::getline(split, each, split_char); token.push_back(each));

:d

答案 1 :(得分:3)

弗雷德·弗林斯通可能使用了strtok()。它早于多线程环境并击败(修改)源字符串。

当使用NULL调用第一个参数时,它会继续解析最后一个字符串。这个功能很方便,但即使在白天也有点不寻常。

答案 2 :(得分:2)

实际上你的代码错了,难怪你会得到意想不到的结果:

char* str = (char*) malloc(sizeof("Madddy"));

应该是

char* str = (char*) malloc(strlen("Madddy") + 1);

答案 3 :(得分:1)

您似乎忘记了第一次(循环外)通过分隔符“d”调用strtok。

strtok工作正常。你应该有一个参考here

对于第二个例子(strtok("ay")):

首先,你调用strtok(str,“d”)。它将寻找第一个“d”,并分隔你的字符串。具体来说,它设置tmp =“Ma”,str =“ddy”(丢弃第一个“d”)。

然后,你打电话给strtok(str,“ay”)。它将在str中查找“a”,但由于您的字符串现在只是“ddy”,因此不会发生匹配。然后它会寻找一个“y”。所以str =“dd”和tmp =“”。

如你所见,打印“Madd”。

答案 4 :(得分:0)

我问了另一个关于functions causing security problems/bad practise functions and the c standard library的问题的启发问题。

从那里引用给我的答案:

  

strtok()常见的陷阱   函数是假设解析的   字符串保持不变,而它   实际上替换了分隔符   带有'\0'的字符。

     

此外,strtok()用于制作   后来打电话给它,直到   整个字符串被标记化。一些   库实现存储   strtok()的内部状态   全局变量,可能会诱发一些   令人讨厌的惊喜,如果是strtok()   从多个线程调用   同一时间。

当您标记了问题C ++时,请使用其他内容!如果你想使用C,我建议你实现你自己的安全标记器。

答案 5 :(得分:0)

由于您将标记更改为C而不是C ++,因此我重写了您的函数以使用printf,以便您可以看到正在发生的事情。 Hoang是对的。你看到正确的输出,但我认为你在同一行打印所有内容,所以你对输出感到困惑。看看Hoang的回答,他正确地解释了发生了什么。另外,正如其他人所说,strtok会破坏输入字符串,所以你必须要小心 - 而且它不是线程安全的。但是如果你需要一个快速的脏标记器,它就可以工作。另外,我更改了代码以正确使用strlen,而不是像Anders正确指出的sizeof。

以下是您的代码修改为更像C的代码:

char* str = (char*) malloc(strlen("Madddy") + 1);
strcpy(str,"Madddy");

char* tmp = strtok(str,"d");
printf ("first token: %s\n", tmp);

do
{
    tmp=strtok(NULL, "ay");
    if (tmp != NULL ) {
       printf ("next token: %s\n", tmp);
    }
} while(tmp != NULL);