我有一个字符串
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
也有begin
和end
功能。它也有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_type
是char
,则不要求最后一个元素是' '
。
好吧,就像你说的,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::memcpy
或std::copy
哪个快,因为我不能说哪一个是快,没有剖析。
我不认为std::strcpy(&v[0],s.c_str());
是一个好的选择。我认为c_str()
是允许重新分配的。
如果你在某种程度上"需要"