字符串初始化和打印

String initialization and printing

本文关键字:打印 初始化 字符串      更新时间:2023-10-16

表3.1在C 引物中的第3.2.1条,第五版状态:

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

我对此的解释是 - 当我们初始化诸如 string s1("value");之类的字符串时,变量 s1包含字符串 value 的副本,而没有 末端的 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
}

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

我之所以问这个,是因为在C中,试图在没有NUL终结器的情况下打印C弦。C 中的字符串不是强制性的,以NUL结束?

我在这里缺少什么?

C 的字符串不是强制性的吗?

取决于您所说的"字符串"。std::string不会以NUL字符结束,因为长度是已知/存储的。std::string::c_str()返回的C风格字符串(又称char*数组(必须结束一个NUL字符,因为长度未知/未存储。

那么,此程序是否将UB调用为S1没有NUL终结器,我们正在打印字符串?

否。std::string提供了"做正确的事情"的operator <<的过载。您不必担心。

我之所以问这个,是因为试图在没有NUL终结器的情况下打印C弦会产生UB。C 的字符串不是必不可少的吗?

这将取决于您使用的标准版本的哪个版本98/03不需要在字符串的末端有空终结器,但c_str基本上迫使您这样做。C 11及以上确实保证了字符串数据末端有一个空终结器。

请注意,由于std::stringoperator <<看起来像

for (size_t i = 0; i < member_variable_size; ++i)
    std::cout << member_variable_data[i]

因此,无论是否有一个。实际上,它几乎必须这样做,因为允许std::string在其中嵌入nulls,并且会像

的方式一样正确打印。
int main() 
{
    std::string foo("hello", 7);
    std::cout << foo;
}

打印

hello

我在这里缺少什么?

此操作员超载将std::string作为第二个参数。因此,std::cout << s1不用null终端打印C弦,您正在调用函数operator <<并将s1传递给它。

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

通常,您可以依靠使用标准库背后的开发人员的能力,即对我来说,使用此超载运算符对我来说很安全:(