当我使用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;
}
程序输出“世界”。 它不应该输出“世界你好”吗?因为我将字符串作为值参数传递给函数a,所以strtok不应该修改原始的... 谁能解释这个伎俩。 谢谢。
答案 0 :(得分:0)
问题是(char*)s.c_str()
,你正在抛弃常量并以你不应该的方式修改string
内容。虽然原始的s
不应该被修改,但是我可能会被一个期望你遵守规则的智能优化所击中。例如,string
的COW实现会发生这种行为。
答案 1 :(得分:0)
c_str()
返回一个const
指针,这是对编译器的一个承诺,指向的东西不会被修改。然后你正在调用strtok来修改它。
当你欺骗编译器时,你将受到惩罚。
答案 2 :(得分:0)
这就是strtok()的工作方式。它使用第一个参数作为缓冲区。通过将其转换为char *,您可以允许它修改字符串。 strtok()不知道原始的std :: string。它还将字符串指针存储在静态变量中,这就是为什么必须在下次使用空指针调用它以继续解析相同的字符串。
顺便说一句,在c ++中,你应该使用std :: istringstream。它不使用内部静态变量,它不是线程安全的。你可以直接将参数提取到int,double等,就像我们使用cin一样。 std :: ostringstring替换sprintf()。