0

当我使用 strtok 标记 C++ 字符串时,会出现一个令人困惑的问题,请参见下面的简单代码:

void a(string s){
    strtok((char*)s.c_str(), " ");
}
int main(){
    string s;
    s = "world hello";
    a(s);
    cout<<s<<endl;
    return 0;
}

程序输出“世界”。它不应该输出“world hello”吗?因为我将字符串作为值参数传递给函数 a,所以 strtok 不应该修改原始 s... 任何人都可以解释这个技巧。谢谢你。

4

3 回答 3

0

问题是(char*)s.c_str(),您正在抛弃 constness 并string以不应该的方式修改内容。虽然s不应该修改原始版本,但我认为您可能已经受到希望您遵守规则的智能优化的打击。例如,COW 的实现string会碰巧表现出这种行为。

于 2011-10-01T03:34:18.727 回答
0

c_str()返回一个const指针,这是对编译器的承诺,指向的东西不会被修改。然后你调用 strtok 来修改它。

当你对编译器撒谎时,你会受到惩罚。

于 2011-10-01T03:35:17.183 回答
0

这就是 strtok() 的工作方式。它使用第一个参数作为缓冲区。通过将其转换为 char*,您允许它修改字符串。strtok() 不知道原始的 std::string。它还将字符串指针存储在静态变量中,这就是为什么您下次必须使用空指针调用它才能继续解析相同的字符串。

顺便说一句,在 C++ 中,您应该改用 std::istringstream 。它不使用不是线程安全的内部静态变量。您可以像使用 cin 一样将参数直接提取到 int、double 等中。std::ostringstring 替换 sprintf()。

于 2011-10-01T03:43:25.840 回答