【问题标题】:is there a way to set the length of a std::string without modifying the buffer content?有没有办法在不修改缓冲区内容的情况下设置 std::string 的长度?
【发布时间】:2015-06-03 12:25:17
【问题描述】:

根据这些问题的答案中的陈述

.. 在 C++11 中,应该可以调用一个 C API 函数,该函数需要一个 char 指针来存储输出,如下所示:

str::string str;
str.reserve(SOME_MAX_VALUE);
some_C_API_func(&str[0]);

但是现在有一种合法的方法来将字符串的大小设置为缓冲区内(以空结尾的)内容的长度吗?像这样的:

str.set_size(strlen(&str[0]));

这是对std::string 的一种非常不美观的滥用,无论如何我听到你说,但我不能在堆栈上创建一个临时的char 缓冲区,所以我必须在堆中创建一个缓冲区并在之后销毁它(我想避免)。

有什么好办法吗?也许不保留,但 调整大小 并在之后调用 erase() 会做到这一点,但感觉不太整洁..

【问题讨论】:

  • 你试过resize吗?
  • 是的,但resize() 似乎修改了内容。至少当我reserve() 缓冲区和resize() 之后,字符串是空的。它似乎与resize(SOME_MAX_VALUE) 一起工作。如果有人说服我这是最复杂的方法,我很高兴:)
  • @frans ,你为什么不使用 std::array 来设置字符串大小??

标签: c++11 char stdstring


【解决方案1】:

您应该使用resize() 而不是reserve(),然后再次使用resize() 来设置最终长度。

否则当你resize()从零到strlen()返回的结果时,数组将被零个字符填充,覆盖你写入的内容。允许字符串这样做,因为它(正确地)假设从当前大小到当前保留容量的所有内容都是未初始化的数据,不包含任何内容。

为了让字符串知道字符实际上是有效的并且应该保留它们的内容,您需要最初使用resize(),而不是reserve()。然后,当您再次resize() 以使字符串更小时,它只会截断不需要的字符串结尾并添加一个空终止符,它不会覆盖您写入的内容。

注意最初的resize() 将零填充字符串,这在您的情况下并非绝对必要,因为您将覆盖您关心的部分,然后丢弃其余部分。如果字符串很长并且分析显示零填充是一个问题,那么您可以这样做:

std::unique_ptr<char[]> str(new char[SOME_MAX_VALUE]);
some_C_API_func(str.get());

【讨论】:

  • unique_ptr 的方法不允许例如使用operator==比较字符串。
猜你喜欢
  • 1970-01-01
  • 2015-03-05
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-06-17
  • 2021-03-20
  • 1970-01-01
相关资源
最近更新 更多