【问题标题】:Deep copy std::string::c_str() to char * [duplicate]深拷贝 std::string::c_str() 到 char * [重复]
【发布时间】: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())

标签: c++ string


【解决方案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 的解决方案。)

【讨论】:

    猜你喜欢
    • 2011-02-09
    • 2017-10-14
    • 1970-01-01
    • 2016-05-07
    • 2011-03-24
    • 2014-01-10
    • 1970-01-01
    • 1970-01-01
    • 2013-03-12
    相关资源
    最近更新 更多