如何有效地将std :: string复制到向量中

时间:2011-09-11 12:12:00

标签: c++ stdvector stdstring

我有一个字符串

std::string s = "Stack Overflow";

我需要复制到矢量中。 这就是我这样做的方式

std::vector<char> v;
v.reserve(s.length()+1);
for(std::string::const_iterator it = s.begin(); it != s.end(); ++it)
{
    v.push_back( *it );
}
v.push_back( '\0' );

但我听说范围操作效率更高。所以我在想这样的事情

std::vector<char> v( s.begin(), s.end());
v.push_back('\0');

但在这种情况下这样更好吗?插入&#39; \ 0&#39;哪个可能的重新分配呢? 我想的另一种方法是这个

std::vector<char> v(s.length()+1);
std::strcpy(&v[0],s.c_str());

也许速度快但可能不安全?
编辑
必须是可以在C函数内使用(读/写)的空终止字符串

3 个答案:

答案 0 :(得分:6)

如果你真的需要一个向量(例如因为你的C函数修改了字符串内容),那么下面的代码应该在一行中给你你想要的东西:

std::vector<char> v(s.c_str(), s.c_str() + s.length() + 1);

由于c_str()返回以null结尾的字符串,因此您只需将其整体复制到向量中即可。

但是,我真的不确定这个构造函数是如何优化的。我知道std::copy是最优化的,所以也许(测量!)以下更快:

std::vector<char> v(s.length() + 1);
std::copy(s.c_str(), s.c_str() + s.length() + 1, v.begin());

如果C函数没有修改字符串,只需直接传递c_str(),然后抛弃常量。这是安全的,只要 C函数只从字符串中读取。

答案 1 :(得分:3)

在大多数情况下,您不需要char的向量,因为std::string几乎是char的容器。 std::string还具有beginend个功能。它还有c_str()函数,它返回 c-string ,您可以将其传递给任何期望const char*的函数,例如:

void f(const char* str); //c-function

std::string s="some string";
f(s.c_str());

那你为什么需要std::vector<char>

在我看来,vector<char>是非常罕见的需求,但如果我需要它,我可能会写这个:

std::vector<char> v(s.begin(), s.end());

对我而言,v.push_back('\0')没有多大意义。如果'\0'value_type,则向量上没有要求将最后一个元素设为char

好吧,如你所说,std::string::c_str()返回const char*,而c-function需要一个非const char*,那么你可以使用std::vector因为你想要利用矢量实现的RAII:

void g(char* s); //c-function

std::vector<char> v(s.begin(), s.end());
s.push_back('\0');

g(&v[0]);

这对我来说似乎很好。但RAII就是你所需要的,那么你还有其他选择:

{
  std::vector<char> memory(s.size()+1);
  char *str = &memory[0]; //gets the memory!
  std::strcpy(str, s.c_str());

  g(str);
  //....

} //<--- memory is destroyed here.

使用std::strcpystd::memcpystd::copy以较快者为准,因为我无法快速说明哪一个 必然 分析

答案 2 :(得分:0)

我认为std::strcpy(&v[0],s.c_str());不是一个好选择。我认为c_str()可以重新分配。

如果您以某种方式“需要”\0处理C-API,请依赖string::c_str()根据要求提供给您。不要以为你需要将它放入char-vector中,大多数事情都可以用字符串本身来处理,就像用矢量一样。

<强>更新

如果您确定使用0初始化了向量,则可以使用c_str来绕过对strncopy的调用:

std::vector<char> v(s.length()+1, 0);  // added '0'
std::strncpy(&v[0],&s[0],s.length());  // no c_str()