在下面的代码中,我希望输出为abc#def。但我得到输出为abcdef。似乎strtok正在修改向量,即使我没有直接将向量传递给strtok函数。我可以知道它是如何发生的吗?
std::vector<std::pair<const std::string, int>> x;
std::vector<std::string> z;
int main()
{
char* pch;
x.push_back(std::make_pair("abc#def", 1));
std::string m = x[0].first;
pch = strtok ((char*)(m.c_str()),"#");
while (pch != NULL)
{
z.push_back(pch);
pch =strtok (NULL, "#");
}
cout<<x[0].first<<endl;
return 0;
}
答案 0 :(得分:0)
std::string
的复制实例可能使用相同的后备缓冲区。即x [0],m实际上可能使用相同的后备缓冲区。
这就是c_str()
成员返回const char *
的原因 - 您不能修改它。
您正在使用C样式转换(char *)来抛弃const。
通常,更好地使用C ++强制转换:static_cast&lt;&gt; / reinterpret_cast&lt;&gt; / dynamic_cast&lt;&gt;和const_cast&lt;&gt;如果你真的需要剥离const。后者仅用于在没有const限定符的情况下连接旧的C代码。您不需要在普通的C ++代码中使用它。
答案 1 :(得分:0)
在您的实现中,c_str()
必须返回对字符串的内部char
缓冲区的引用,而不进行任何复制。来自glibc strtok
:
BUGS
使用这些功能时要小心。如果您确实使用它们,请注意:
- 这些函数修改了他们的第一个参数。
所以,是的,strtok
应用于从c_str()
返回的指针将修改字符串缓冲区。
您应该使用std::getline
代替strtok
将字符串拆分为#
:
std::vector<std::pair<const std::string, int>> x;
int main() {
x.push_back(std::make_pair("abc#def", 1));
std::string m = x[0].first;
std::string token;
while(std::getline(m, token, '#')) {
std::cout << token << std::endl;
}
cout<< x[0].first <<endl;
return 0;
}
或者,如果确实需要使用strtok
,至少要复制c_str()
与strdup
返回的缓冲区(并记住free()
}它)。
答案 2 :(得分:0)
而是使用strtok
使用find_first_of
&amp; find_first_not_of
string
方法
像这样:
using namespace std;
int main () {
string s="abc#def";
string temp = s,res;
while(temp.size()){
size_t st,en;
st = temp.find_first_not_of("#");
en = temp.find_first_of("#",st);
res= temp.substr(st,en);
cout<<res.c_str()<<endl;
temp=(en == string::npos) ? "" : temp.substr(en);
}
return 0;
}