如何有效地将std::string复制到vector

How to efficiently copy a std::string into a vector

本文关键字:string 复制 vector std 有效地      更新时间:2023-10-16

我有一个字符串

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( '' );

但是我听说范围运算更有效率。所以我想这样写

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

但是在这种情况下这样更好吗?插入''时可能的重新分配怎么办?
我考虑的另一种方法是

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

可能快但可能不安全?
编辑
必须是一个可以在C函数中使用(读/写)的以空结尾的字符串

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

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

由于c_str()返回的是一个以空结尾的字符串,所以你可以把它整个复制到vector中。

然而,我实际上不确定这个构造函数是如何优化的。我确实知道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(),抛弃const-ness。这是安全的,只要C函数只从字符串中读取

在大多数情况下,您不需要char的向量,因为std::string几乎是char的容器。std::string也有beginend功能。它也有c_str()函数返回c字符串你可以传递给任何需要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('')没有多大意义。对于vector,如果value_typechar,则不要求最后一个元素是''

好吧,就像你说的,std::string::c_str()返回const char*, c函数需要一个非const char*,然后你可以使用std::vector,因为你想利用RAII矢量实现:

void g(char* s); //c-function
std::vector<char> v(s.begin(), s.end());
s.push_back('');
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::strcpy, std::memcpystd::copy哪个快,因为我不能说哪一个是快,没有剖析。

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

如果你在某种程度上"需要"来处理c - api,那么依靠string::c_str()来根据请求提供给你。我不认为你需要把它放入char - vector中,大多数事情你可以像使用vector一样使用字符串本身。

:

如果你确保你的向量是用0 s初始化的,你可以通过使用strncopy:

来规避对c_str的调用。
std::vector<char> v(s.length()+1, 0);  // added '0'
std::strncpy(&v[0],&s[0],s.length());  // no c_str()