有没有一种方法可以设置std::string的长度而不修改缓冲区的内容?

15
根据这些问题的回答中所述:

.. 在C++11中,应该可以通过以下方式调用接受char指针以存储输出的C API函数:

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 吗? - Kerrek SB
是的,但是resize()似乎会修改内容。至少当我使用reserve()缓冲区并在之后使用resize()时,字符串之后为空。它似乎与resize(SOME_MAX_VALUE)一起使用。如果有人说服我这是最复杂的方法,我很高兴 :) - frans
@frans,为什么你不使用std :: array来设置字符串大小?? - MCHAppy
2个回答

12

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

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

为了使字符串知道字符实际上是有效的,并且它们的内容应该被保留,你需要最初使用resize()而不是reserve()。然后当你再次使用resize()来使字符串变得更小时,它只会截断不需要的字符串末尾并添加空终止符,而不会覆盖你已经写入其中的内容。

N.B. 最初的resize()将对字符串进行零填充,在你的情况下这并不是绝对必要的,因为你将覆盖你关心的部分,然后丢弃其余的部分。如果字符串非常长,性能分析显示零填充是一个问题,那么你可以这样做:

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

2
ن½؟用unique_ptrçڑ„و–¹و³•ن¸چه…پ许ن½؟用operator==و¯”较ه­—符ن¸²م€‚ - Ruslan

0

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接