c++ 如何从一个可能包含或不包含null的缓冲区构造一个`std::string`?

qgelzfjb  于 2023-05-08  发布在  其他
关注(0)|答案(2)|浏览(167)

我有一个char的缓冲区(为了简单起见,假设是一个固定大小的数组),我想从它构造一个std::string。所述缓冲区可以是空终止的,或者其内容可以达到并包括最后一个字符。如果缓冲区确实包含一个或多个空值,则它们不应该在结果string中结束。复制应该在第一个null * 或缓冲区末尾 * 停止,以先到者为准。
这似乎是一个很常见的事情,但在查看std::string API时,解决方案对我来说并不明显。

  • std::string有一个通过const char *获取范围和长度的构造函数,但很高兴地继续过去的空值并将它们复制到字符串中。
  • 在构造string之前调用缓冲区中的std::strlen()不是一个选项,因为strlen首先要求字符串以null结尾。
  • 我们可以使用上面的构造函数来创建一个包含null的string,然后将其大小调整到第一个null之前,但这会浪费内存,因为string将被过度分配。

什么是最好的和/或惯用的方法来做到这一点?

qq24tv8q

qq24tv8q1#

与许多关于C++标准库的问题一样,答案是从迭代器的Angular 来考虑问题。

std::string stringFromBuffer(const auto & buffer)
{
    return std::string(std::begin(buffer),
                       std::find(std::begin(buffer), std::end(buffer), '\0'));
}

std::string有一个接受两个迭代器firstlast的构造函数。string将通过从first复制到last(但不包括last)来创建。
所以first显然应该是我们缓冲区的开始,而last应该是我们缓冲区中的第一个null或超过缓冲区结尾的null。方便的是,这正是调用std::find在缓冲区中搜索'\0'将返回的内容。

voj3qocg

voj3qocg2#

下面是一个已知大小的字符数组的简单方法。它类似于帕克的答案,但只是在构造函数参数中完成,并且特定于字符数组的问题。

#include <algorithm> // std::find
#include <iostream>
#include <string>

int main() {
  const char c[] = {'a', 'b', 'c', 'd', 'e'}; // prints abcde
  // const char c[] = { 'a','b','\0','d','\0' };    // test alternate: prints ab
  // const char c[] = { 'a','b','\0','d','e' };     // test alternate: prints ab
  std::string s{c, std::find(c, c + sizeof c, '\0')};
  std::cout << s << '\n';
  return 0;
}

相关问题