字符串初始化和打印

时间:2019-05-02 14:51:13

标签: c++ string

C++ Primer, Fifth edition中,条款3.2.1下的表3.1指出:

  

string s3("value")-> s3是字符串文字的副本,不是   包括空值。

我对此的解释是-当我们初始化string s1("value");之类的字符串时,变量s1包含字符串value的副本 {{ 1}}末尾的字符。

NUL

那么,此程序是否由于#include <iostream> using std::cin; using std::string; using std::cout; using std::endl; int main(void) { string s1("value"); cout << s1 << endl; // prints - value } 没有s1终止符而调用UB,而我们正在打印字符串?

我之所以这样问是因为,在C语言中,尝试打印不带NUL终止符的c字符串会产生UB。 C ++中的字符串以NUL结尾是否不是强制性的?

我在这里想念什么?

3 个答案:

答案 0 :(得分:3)

  

不是强制C ++中的字符串以NUL结尾吗?

取决于“字符串”的含义。 std::string不能以nul字符结尾,因为长度是已知的/已存储的。 char*返回的C样式字符串(也称为std::string::c_str()数组)必须以空字符结尾,因为长度未知/未存储。

答案 1 :(得分:2)

  

那么,此程序是否调用UB,因为s1没有NUL终止符,而我们正在打印字符串?

不。 std::string提供了operator <<的重载,它“做正确的事”。您不必担心。

  

我问这是因为尝试在没有NUL终止符的情况下打印c字符串会产生UB。 C ++中的字符串以NUL结尾不是强制性的吗?

这取决于您所使用的C ++ 98/03标准的版本,并不需要在字符串末尾添加空终止符,但是c_str基本上迫使您这样做。尽管C ++ 11和更高版本确实可以保证在字符串数据的末尾有一个空终止符。

请注意,因为std::string的{​​{1}}看起来像

operator <<

因此无论是否存在它都将起作用。实际上,由于for (size_t i = 0; i < member_variable_size; ++i) std::cout << member_variable_data[i] 可以在其中嵌入空值,因此它将非常正确地进行打印,就像如何

std::string

打印

int main() 
{
    std::string foo("h\0ell\0o", 7);
    std::cout << foo;
}

答案 2 :(得分:1)

  

我在这里想念什么?

This运算符重载,它以std::string作为第二个参数。因此,std::cout << s1不会在没有空终止符的情况下打印c字符串,您正在调用函数operator <<并将s1传递给它。

  

那么,此程序是否因为s1没有NUL终止符而调用UB,而我们正在打印字符串?

通常,您可以依赖所使用的标准库背后的开发人员的能力,即,使用此重载运算符对我来说似乎很安全:)