将以null结尾的char数组复制到符合缓冲区长度的std::字符串中

Copy null terminated char array to std::string respecting buffer length

本文关键字:缓冲区 std 字符串 结尾 null char 数组 复制 将以      更新时间:2023-10-16

也许只是缺少咖啡,但我正试图从一个已知最大长度的空终止char数组创建一个std::string,我不知道该怎么做。

auto s = std::string(buffer, sizeof(buffer));

是我最喜欢的候选者,但由于C++字符串不是以null结尾的,因此无论包含什么"\0",该命令都将复制sizeof(buffer)字节。

auto s = std::string(buffer);

从CCD_ 4拷贝直到找到CCD_。这几乎是我想要的,但我不能信任接收缓冲区,所以我想提供最大长度。

当然,我现在可以像这样集成strnlen()

auto s = std::string(buffer, strnlen(buffer, sizeof(buffer)));

但这似乎很糟糕——它遍历了缓冲区两次,我必须处理像string.hstrnlen()这样的C工件(而且很难看)。

在现代C++中我该如何做到这一点?

const char* end = std::find(buffer, buffer + sizeof(buffer), '');
std::string s(buffer, end);

类似的东西可以在一次通过中工作。

auto eos = false;
std::string s;
std::copy_if(buffer, buffer + sizeof(buffer), std::back_inserter(s),
  [&eos](auto v) {
    if (!eos) {
      if (v) {
        return true;
      }
      eos = true;
    }
    return false;
  });

如果您想要单程解决方案,请从以下内容开始:

template<class CharT>
struct smart_c_string_iterator {
  using self=smart_c_string_iterator;
  std::size_t index = 0;
  bool is_end = true;
  CharT* ptr = nullptr;
  smart_c_string_iterator(CharT* pin):is_end(!pin || !*pin), ptr(pin) {}
  smart_c_string_iterator(std::size_t end):index(end) {}
};

现在,对它进行美化,使其成为一个完整的随机访问迭代器。大多数操作都非常简单(++等应该同时推进ptrindex),除了==!=

friend bool operator==(self lhs, self rhs) {
  if (lhs.is_end&&rhs.is_end) return true;
  if (lhs.index==rhs.index) return true;
  if (lhs.ptr==rhs.ptr) return true;
  if (lhs.is_end && rhs.ptr && !*rhs.ptr) return true;
  if (rhs.is_end && lhs.ptr && !*lhs.ptr) return true;
  return false;
}
friend bool operator!=(self lhs, self rhs) {
  return !(lhs==rhs);
}

我们还需要:

template<class CharT>
std::pair<smart_c_string_iterator,smart_c_string_iterator>
smart_range( CharT* ptr, std::size_t max_length ) {
  return {ptr, max_length};
}

现在我们这样做:

auto r = smart_range(buffer, sizeof(buffer));
auto s = std::string(r.first, r.second);

在每一步中,我们都会在进行复制时检查缓冲区长度和空终止。

现在,Ranges v3引入了sentinal的概念,它允许您在降低运行时成本的情况下执行类似于上面的操作。或者你也可以手工制作同等的解决方案。