我有一个字符串
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函数内使用(读/写)的空终止字符串
答案 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
还具有begin
和end
个功能。它还有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::strcpy
,std::memcpy
或std::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()