深拷贝 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_typestd::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 指针? [复制]

使用 std::string.c_str() 作为另一个方法的参数时的段错误

C++ 中的 StringStream/c_str() 损坏