将null终止的char数组复制到std :: string,考虑缓冲区长度

fra*_*ans 14 c++ arrays string char c++11

也许这只是缺少咖啡,但我正在尝试std::stringchar已知最大长度的空终止数组创建一个我不知道的,如何做到这一点.

auto s = std::string(buffer, sizeof(buffer));
Run Code Online (Sandbox Code Playgroud)

..是我最喜欢的候选者,但由于C++字符串不是以空值终止的,因此该命令将复制sizeof(buffer)字节而不管任何包含的'\ 0'.

auto s = std::string(buffer);
Run Code Online (Sandbox Code Playgroud)

.. 发现buffer直到\0找到.这几乎是我想要的,但我不能相信接收缓冲区,所以我想提供一个最大长度.

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

auto s = std::string(buffer, strnlen(buffer, sizeof(buffer)));
Run Code Online (Sandbox Code Playgroud)

但是,这似乎是肮脏的-它遍历缓冲区两次,我必须处理C-工件,如string.hstrnlen()(和它的丑陋).

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

Joh*_*nck 19

const char* end = std::find(buffer, buffer + sizeof(buffer), '\0');
std::string s(buffer, end);
Run Code Online (Sandbox Code Playgroud)

  • 换句话说,`std :: string s(buffer);`已遍历缓冲区两次,除非我们不介意过度分配,否则额外的大小限制结果不会有用.原则上你可以进行一系列指数增加的分配(比如`vector`),但是当你把所有中间副本加起来时,你仍然会大约两次遍历数据. (4认同)
  • @songyuanyao:取决于你如何看待它,是(一次遍历找到长度,然后一次复制字节).但这是不可避免的,因为在检查长度之前,您根本无法知道要分配的正确大小,并且在分配之前无法复制字节.无论实际内容有多短,真正的单遍解决方案总是会分配`sizeof(buffer)`,这可能会显着增加内存消耗. (3认同)