将非null终止向量<char>转换为字符串

时间:2017-08-03 18:06:17

标签: c++ string vector constructor constructor-overloading

我有一个非空终止的字符向量,如何构造一个新字符串并让它自动将\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())

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

3 个答案:

答案 0 :(得分:7)

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

另一方面,

std::string b(v.begin(), v.end());是完全安全的,并且会为您提供与该向量具有相同内容的std::string

答案 1 :(得分: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()); 

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

答案 2 :(得分:1)

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

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