【发布时间】:2015-11-02 19:58:35
【问题描述】:
我从 strtok 和 strtrok_r 函数中得到了意外的行为:
queue<string> tks;
char line[1024];
char *savePtr = 0;
while(true)
{
//get input from user store in line
tks.push(strtok_r(line, " \n", &savePtr)); //initial push only works right during first loop
char *p = nullptr;
for (...)
{
p = strtok_r(NULL, " \n", &savePtr);
if (p == NULL)
{
break;
}
tks.push(p);
}
delete p;
savePtr = NULL;
//do stuff, clear out tks before looping again
}
我尝试使用strtok 并意识到在第二个循环期间,初始推送没有发生。我尝试使用可重入版本strtok_r 来控制保存的指针在第二次循环期间指向的内容,方法是在再次循环之前确保它为空。
tks 仅在第一次通过循环时正确填充 - 后续循环根据 line 的长度给出不同的结果
我在这里错过了什么?
【问题讨论】:
-
minimal reproducible example 或者它没有发生。
-
重要有趣的事实:strtok(和 strtok_r)不
new指针被分配给p。它获取您输入的字符串line并将其切碎,插入一个空字符来代替下一个找到的分隔符,然后返回一个指向现在以空结尾的字符串的第一个字符的指针。所以delete p;实际上是在尝试delete的一部分line。卡繁荣。好的。也许不是,因为由于循环退出条件,您真正删除的是 NULL 。不过,可能无论如何都不应该这样做。 -
Gotcha...虽然这不会影响我的问题:(
-
建议:既然您已经知道您有来自用户的一行,那么
\n分隔符似乎有点多余。您可以将line放入std::stringstream linestream(line);,然后std::getline(linestream, word, ' ');其中word是std::string,然后是tks.push(word);。
标签: c++ parsing tokenize strtok