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

时间:2014-07-31 08:34:58

标签: c++ string c++11

我正在将一些数据从流中复制到一个字符串中,所以我考虑使用实际的字符数来调整字符串的大小,再添加一个用于终止字符串的字符串,如下所示:

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()会添加额外的终止字符本身?这意味着我不必担心在调用\0后附加read(&data[0], count)

2 个答案:

答案 0 :(得分:4)

来自标准的引用§21.4.7.1basic_string访问者[string.accessors] 表示std::string具有保证的空终止缓冲区。

另外根据标准§21.4.4/ 6-8 basic_string capacity [string.capacity]:

  

void resize(size_type n, charT c);

     

6需要:n <= max_size()

     

7如果length_error则抛出n > max_size()

     

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

     
    
      

- 如果n <= size(),该函数将*this指定的字符串替换为长度为n的字符串,其元素是指定的原始字符串的初始元素的副本*this

             

- 如果n > size(),该函数会将*this指定的字符串替换为长度为n的字符串,其第一个size()元素是原始文件的副本由*this指定的字符串,其余元素全部初始化为c

    
  
     

void resize(size_type n);

     

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

解释上面的std::string::resize不会影响字符串缓冲区的终止空字符。

现在你的代码:

语句std::string copy;定义一个空字符串(即copy.size() == 0)。

语句copy.resize(count + 1);,因为(n == 5) > 0将使用填充\0的长度为5的字符串替换副本(即空字符)。

现在声明stream.read(&copy[0], count); std::stream::read只会复制一个数据块,而不会检查其内容,也不会在末尾添加空字符。

换句话说,它只会将copy的前4个空字符替换为“data”。 copy的大小不会改变,它仍然是一个5大小的字符串。也就是说,copy缓冲区的内容将是“data \ 0 \ 0”。

因为copy[count] = 0;已经copy[4],所以调用\0是多余的。但是,您的字符串不是“数据”,而是“数据\ 0”。

答案 1 :(得分:3)

不,你不必。 string类抽象出“空终止字符序列”的概念,因此您不必再担心它了。

此外,返回的字符串的大小不计算终止字符,这与我提到的行为一致,因为如果您不必处理终止字符,则无需了解它。您的字符串只是您想要操作的字符,而不关心与您的实际数据无关的“实用程序”字符。