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

发布于 2024-12-04 03:59:17 字数 668 浏览 1 评论 0原文

我有一个字符串

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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

情感失落者 2024-12-11 03:59:17

如果您确实需要一个向量(例如,因为您的 C 函数修改了字符串内容),那么以下内容应该在一行中为您提供您想要的内容:

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

Since 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() 即可,并抛弃 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:

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

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:

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

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.

格子衫的從容 2024-12-11 03:59:17

在大多数情况下,您不需要 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 呢?

在我看来,vector 是一种非常非常罕见的需求,但如果我需要它,我可能会这样写:

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

对我来说,v.push_back('\0') 没有多大意义。如果 value_typechar,则向量没有最后一个元素为 '\0' 的要求。

好吧,正如你所说,std::string::c_str() 返回 const char*,而 c 函数需要一个非常量 char*< /code> ,那么你可以使用 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< /code> 哪个快,因为我无法在不进行分析的情况下说哪个必然快。

In most cases, you don't need vector of char, as std::string pretty much is a container of char. std::string also have begin and end functions. And it also have c_str() function which returns the c-string which you can pass to any function which expects const char*, such as this:

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

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

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:

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

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 the value_type is char.

Alright, as you said, std::string::c_str() returns const char*, and the c-function needs a non-const char* , then you can use std::vector because you want to take advantage of RAII which vector implements:

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

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

g(&v[0]);

which seems fine to me. But RAII is all that you need, then you've other option as well:

{
  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.

Use std::strcpy, std::memcpy or std::copy whichever is fast, as I cannot say which one is necessarily fast, without profiling.

放手` 2024-12-11 03:59:17

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

如果您以某种方式“需要”\0 来处理 C-API,请依靠 string::c_str() 根据请求向您提供它。不要认为您需要将其放入字符向量中,您可以像使用向量一样对字符串本身执行大多数操作。

更新

如果您确保向量使用 0 进行初始化,则可以使用 strncopyc_str 的调用代码>:

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

I don't think std::strcpy(&v[0],s.c_str()); is a good choice. I think c_str() is allowed to re-allocate.

If you somehow "need" the \0 for dealing with C-APIs, then rely on string::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 0s, you can circumvent the call to c_str by using strncopy:

std::vector<char> v(s.length()+1, 0);  // added '0'
std::strncpy(&v[0],&s[0],s.length());  // no c_str()
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文