有没有办法在不修改缓冲区内容的情况下设置std :: string的长度?

时间:2015-03-30 13:06:52

标签: c++11 char stdstring

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

..在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()会这样做,但它感觉不是很好..

1 个答案:

答案 0 :(得分:6)

您应该使用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());