如何有效地将 std::string 复制到向量中
我有一个字符串
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');
但是在这种情况下这样更好吗?插入“\0”时可能会发生重新分配怎么办?
我正在考虑的另一种方法是
std::vector<char> v(s.length()+1);
std::strcpy(&v[0],s.c_str());
也许很快但可能不安全?
编辑
必须是一个可以在 C 函数中使用(读/写)的空终止字符串
I have a string
std::string s = "Stack Overflow";
That I need to copy into a vector.
This is how I am doing it
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' );
But I hear range operation are more efficient. So I am thinking something like this
std::vector<char> v( s.begin(), s.end());
v.push_back('\0');
But is this better in this case? What about the potential re-allocation when inserting '\0'?
Another approach I am thinking is this
std::vector<char> v(s.length()+1);
std::strcpy(&v[0],s.c_str());
Perhaps fast but potentially unsafe?
EDIT
Has to be a null terminated string that can be used ( read/write ) inside a C function
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
如果您确实需要一个向量(例如,因为您的 C 函数修改了字符串内容),那么以下内容应该在一行中为您提供您想要的内容:
Since
c_str()
返回一个以 null 结尾的字符串,您可以将其整个复制到向量中。但是,我实际上不确定这个构造函数的优化程度。我确实知道
std::copy
已经得到了优化,所以也许(测量!)以下更快:如果C函数不修改字符串,只需直接传递
c_str()
即可,并抛弃 const 性。这是安全的,只要 C 函数只读取字符串。If you really need a vector (e.g. because your C function modifies the string content), then the following should give you what you want, in one line:
Since
c_str()
returns a null-terminated string, you can just copy it whole into the vector.However, I’m not actually sure how optimised this constructor is. I do know that
std::copy
is as optimised as it gets, so perhaps (measure!) the following is faster:If the C function doesn’t modify the string, just pass
c_str()
directly, and cast away const-ness. This is safe, as long as the C function only reads from the string.在大多数情况下,您不需要
char
向量,因为std::string
几乎是char
的容器。std::string
还具有begin
和end
函数。它还具有c_str()
函数,该函数返回 c-string,您可以将其传递给任何需要const char*
的函数,例如这:那么为什么你需要
std::vector
呢?在我看来,
vector
是一种非常非常罕见的需求,但如果我需要它,我可能会这样写:对我来说,
v.push_back('\0')
没有多大意义。如果value_type
是char
,则向量没有最后一个元素为'\0'
的要求。好吧,正如你所说,
std::string::c_str()
返回const char*
,而 c 函数需要一个非常量char*< /code> ,那么你可以使用
std::vector
因为你想利用向量实现的 RAII:这对我来说似乎很好。但 RAII 就是您所需要的,那么您还有其他选择:
使用
std::strcpy
、std::memcpy
或std::copy< /code> 哪个快,因为我无法在不进行分析的情况下说哪个必然快。
In most cases, you don't need vector of
char
, asstd::string
pretty much is a container ofchar
.std::string
also havebegin
andend
functions. And it also havec_str()
function which returns the c-string which you can pass to any function which expectsconst char*
, such as this:So why would you ever need
std::vector<char>
?In my opinion,
vector<char>
is a very very rare need but if I ever need it, I would probably write this:And to me,
v.push_back('\0')
doesn't make much sense. There is no such requirement on vector to have the last element as'\0'
if thevalue_type
ischar
.Alright, as you said,
std::string::c_str()
returnsconst char*
, and the c-function needs a non-constchar*
, then you can usestd::vector
because you want to take advantage of RAII which vector implements:which seems fine to me. But RAII is all that you need, then you've other option as well:
Use
std::strcpy
,std::memcpy
orstd::copy
whichever is fast, as I cannot say which one is necessarily fast, without profiling.我认为
std::strcpy(&v[0],s.c_str());
不是一个好的选择。我认为c_str()
可以重新分配。如果您以某种方式“需要”
\0
来处理 C-API,请依靠string::c_str()
根据请求向您提供它。不要认为您需要将其放入字符向量中,您可以像使用向量一样对字符串本身执行大多数操作。更新:
如果您确保向量使用
0
进行初始化,则可以使用strncopyc_str
的调用代码>:I don't think
std::strcpy(&v[0],s.c_str());
is a good choice. I thinkc_str()
is allowed to re-allocate.If you somehow "need" the
\0
for dealing with C-APIs, then rely onstring::c_str()
to provide it to you, on request. In dont think that you need to put it into a vector-of-char, most things you can do with the string itself like with a vector.Update:
If you make sure your vector gets initialized with
0
s, you can circumvent the call toc_str
by usingstrncopy
: