2

我有一个非空终止的字符向量,如何构造一个新字符串并让它自动插入\0到字符串的末尾?

std::vector<char> v;
v.push_back('H');
v.push_back('i');
v.push_back('!');
//v.push_back('\0'); <~ without using this line

std::string a(v.data());
std::string b(v.begin(), v.end()); // same meaning as b(v.data(), v.size())

两者之间的正确构造函数是什么?

4

3 回答 3

7

std::string a(v.data());是不正确的。构造函数需要一个指向空终止字符序列的指针。不给它一个是未定义的行为。

std::string b(v.begin(), v.end());另一方面是完全安全的,并且会给你一个std::string与向量相同的内容。

于 2017-08-03T18:10:51.967 回答
5

这个构造函数:

std::string a(v.data());

期望参数是指向以 null 结尾的 C 样式字符串的第一个字符的指针。由于v.data()不指向以 null 结尾的字符串,因此此构造函数调用具有未定义的行为。

您可以再添加一个参数以使构造函数调用有效:

std::string a(v.data(), v.size());

也就是说,而不是使用这个构造函数:

basic_string(const charT* s, const Allocator& a = Allocator());

你可以使用这个构造函数:

basic_string(const charT* s, size_type n, const Allocator& a = Allocator());

在这种情况下,字符串将完全根据v.size()存储在向量中的字符构建。

这个构造函数:

std::string b(v.begin(), v.end()); 

是有效的,实际上是另一种形式来提供一个没有空终止符的范围,与前面的构造函数相比。

于 2017-08-03T18:17:23.827 回答
1

你的第一次尝试会失败;std::string 可以从以空字符结尾的字符数组构造,但如果没有空字符,构造函数将继续读取向量不拥有的内存,直到找到空字节为止。

您的第二次尝试是解决方案;std:;string 将从迭代器中复制字符并自动添加终止的空字符。

于 2017-08-03T18:13:40.417 回答