【问题标题】:c++ strtok in function changes original string value as parameter函数中的c ++ strtok将原始字符串值更改为参数
【发布时间】:2011-10-01 11:43:25
【问题描述】:

当我使用 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... 谁能解释一下这个技巧。 谢谢。

【问题讨论】:

标签: c++ string strtok


【解决方案1】:

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

【讨论】:

  • 谢谢。顺便说一句,你知道如何安全高效地将 c++ 字符串转换为 char*,这样我就可以在 strtok 中毫无问题地使用 char* 了吗?
  • @zwx:如果你打算修改char*,那么你需要复制它。
【解决方案2】:

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

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

【讨论】:

  • 一个std::string 没有空值问题。
【解决方案3】:

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

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

【讨论】:

    猜你喜欢
    • 2021-08-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-03-05
    • 1970-01-01
    • 2020-04-18
    相关资源
    最近更新 更多