std::string::resize()方法是否管理终止字符?

8
我正在将一些数据从流中复制到字符串中,所以我考虑使用实际字符数加上一个终止字符的方式重新调整字符串大小,像这样:

std::istringstream stream { "data" };
const std::size_t count = 4;

std::string copy;
copy.resize(count + 1);

stream.read(&copy[0], count);
copy[count] = 0;

然而,在这种情况下,copy 表示它的大小为 5(这与我调用 resize(5) 一致)。这是否意味着 resize() 将自动添加额外的终止字符?这就意味着在调用 read(&data[0], count) 后无需担心追加 \0

1
C++11及以后的std::string保证了空终止缓冲区。 - 101010
2个回答

6
不需要。"string"类抽象了"空终止字符序列"的概念,因此您不再需要担心它。
另外,返回的字符串大小不包括终止字符,这与我提到的行为一致,因为如果您不必处理终止字符,那么您就不必知道它。您的字符串只是要操作的字符,没有任何关于实际数据的"实用"字符的顾虑。

4
标准中的引用§21.4.7.1 basic_string访问器[string.accessors]表明,std::string具有保证的空终止缓冲区。
同样根据标准§21.4.4/6-8 basic_string容量[string.capacity]:

void resize(size_type n, charT c);

6 要求:n <= max_size()

7 抛出:n > max_size()时抛出length_error

8 效果:更改由*this指定的字符串的长度如下:

- 如果n <= size(),则函数将用原始字符串的初始元素的副本替换由*this指定的字符串。

- 如果n > size(),则函数将使用由*this指定的原始字符串的前size()个元素的副本来替换字符串,并且其余元素都初始化为c

void resize(size_type n);

9 效果:resize(n,charT())

解释上述std::string::resize不会影响字符串缓冲区的终止空字符。
现在看一下您的代码:
语句std::string copy;定义了一个空字符串(即copy.size() == 0)。
由于(n == 5) > 0,所以语句copy.resize(count + 1);将把copy替换为长度为5且填充有\0(即null字符)的字符串。
现在,在语句stream.read(&copy[0], count);中,std::stream::read将简单地复制一块数据,而不检查其内容也不在末尾添加空字符。
换句话说,它只会用"data"替换copy的前4个空字符。 copy的大小不会改变,仍然是一个大小为5的字符串。也就是说,copy的缓冲区内容将是"data\0\0"。
因为copy[4]已经是\0了,所以调用copy[count] = 0;是多余的。然而,你的字符串不是"data",而是"data\0"。

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