目前我有一个复杂的函数,我和我们的团队都不想重构它来使用std :: string,并且它需要修改char *。我如何正确地将string :: c_str()的深度副本制作成char *? 我不想修改字符串内部存储的char *。
char *cstr = string.c_str();
因为c_str()是const,所以失败了。
const std::string::size_type size = string.size();
char *buffer = new char[size + 1]; //we need extra char for NUL
memcpy(buffer, string.c_str(), size + 1);
std::string::size_type
或 std::size_t
。 - syamstd::vector<char>
为您完成此操作,并将数组作为v.data()
或&v[0]
访问。甚至可以使用另一个string
,如果您不介意边缘未定义的行为。 - Mike Seymour不要修改现有的函数,而是创建一个充当包装器的重载。假设现有函数是ret_type f(char *)
,那么我会编写类似以下的重载:
ret_type f(std::string s) {
return f(&s[0]);
}
传递参数时,将字符串 s
按值而非按引用传递,以最小化获取字符串副本的努力。
理论上讲,在 C++03 之前并不能保证这种方式能够正常工作(即,一个字符串的缓冲区并不能保证连续)。实际上,委员会添加了这个保证是因为没有人知道 std::string
的实现会做其他的事情。
同样地,它理论上可能缺少 NUL 终止符。如果您担心这种可能性,可以使用 return f(const_cast<char *>(s.c_str()));
,或在返回之前添加一个 s.push_back('\0');
:
ret_type f(std::string s) {
s.push_back('\0');
return f(&s[0]);
}
s.push_back('\0')
,以确保安全。而且你最后一段代码肯定是指的const_cast
。 - James Kanzestd::vector<char> tmp( string.begin(), string.end() );
tmp.push_back( '\0' );
function( &tmp[0] );
std::string
并使用&stringCopy[0]
。 这句话的意思是询问是否为C++11语法,并建议通过复制std::string
并使用&stringCopy[0]
来实现某个目的。 - chrisstrdup
,new/strcpy
,@chris的建议,……由您选择。 - syam