深拷贝 std::string::c_str() 到 char * [重复]
Posted
技术标签:
【中文标题】深拷贝 std::string::c_str() 到 char * [重复]【英文标题】:Deep copy std::string::c_str() to char * [duplicate] 【发布时间】:2013-08-31 18:16:51 【问题描述】:目前我有一个复杂的函数,我自己和我们的团队不想重构以利用 std::string 并且它需要一个 char* 已修改。我如何正确地将 string::c_str() 的深拷贝制作成 char*?我不希望修改字符串内部存储的 char*。
char *cstr = string.c_str();
失败,因为 c_str() 是 const。
【问题讨论】:
这是 C++11 吗?复制std::string
并使用&stringCopy[0]
。
strdup
, new/strcpy
, @chris' 的建议,...你可以选择。
sprintf(cstr,"%s", somestring.c_str())
【参考方案1】:
你可以这样做:
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
.
@syam 啊,你是绝对正确的 :)
别忘了删除它。或者更好的是,让std::vector<char>
为您执行此操作,并以v.data()
或&v[0]
访问数组。甚至是另一个string
,如果您不介意边界未定义的行为。【参考方案2】:
与其修改现有函数,不如创建一个充当包装器的重载。假设现有函数是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
。
@JamesKanze:哎呀——是的,当然。【参考方案3】:
显而易见的解决方案是:
std::vector<char> tmp( string.begin(), string.end() );
tmp.push_back( '\0' );
function( &tmp[0] );
(不过,我更喜欢 Jerry Coffin 的解决方案。)
【讨论】:
以上是关于深拷贝 std::string::c_str() 到 char * [重复]的主要内容,如果未能解决你的问题,请参考以下文章
std::string::c_str() 结果的生命周期是多少?
std::string::c_str() 结果的生命周期是多少?
C++string类型与C语言字符数组的转换 std::string.c_str()函数
为啥我仍然可以在字符串范围之外访问 std::string::c_str() 返回的 char 指针? [复制]