添加'\0';到std::string 为什么C++标准允许如下? #包括 #包括 int main() { std::string s(10,'\0');//s.length()现在是10 std::cout

添加'\0';到std::string 为什么C++标准允许如下? #包括 #包括 int main() { std::string s(10,'\0');//s.length()现在是10 std::cout,c++,string,stl,C++,String,Stl,NULchar'\0'是c样式字符串的结尾字符,而不是std::strings。但是,它支持此字符从常量字符指针获取值,以便它可以找到c样式字符串的结尾。否则,它将与其他字符一样处理 为什么标准允许以下内容 因为设计C++字符串的人决定了应该允许这样的事情。我不确定是否有人是设计C++字符串的团队的一部分。所以,既然你自己说标准允许,那就是它的方式,我怀疑它会改变。 p>有时有一个字符串可以包含“任何东西”,这是很实际的。我可以考虑几个例子,当我不得不处理C样式字符串不能包含零字节的事实时,随

NUL
char
'\0'
c样式字符串的结尾字符,而不是
std::string
s。但是,它支持此字符从常量字符指针获取值,以便它可以找到c样式字符串的结尾。否则,它将与其他字符一样处理

为什么标准允许以下内容

因为设计C++字符串的人决定了应该允许这样的事情。我不确定是否有人是设计C++字符串的团队的一部分。所以,既然你自己说标准允许,那就是它的方式,我怀疑它会改变。


<> p>有时有一个字符串可以包含“任何东西”,这是很实际的。我可以考虑几个例子,当我不得不处理C样式字符串不能包含零字节的事实时,随着长C样式字符串花费很长时间来查找长度,C++字符串的主要好处是它们不受限制。“你可以在里面放什么”-这在我的书中是一件好事。

不确定这里有什么问题

<> > <代码> > 0代码>中间的代码> STD::String 改变No.NULL字符被视为任何其他字符。唯一可以改变的是,如果你使用了.cString()/Case>,它接受了空结束的字符串。但是这不是<代码> .cStr.()的问题。
,仅使用专门处理
'\0'
的函数

如果您想知道有多少个字符将此字符串视为以null结尾的字符串,请使用

size_t len = strlen(s.c_str());
请注意,这是O(n)操作,因为这就是strlen的工作方式

如果你问为什么
+=
操作符不向字符串中添加string literal
“hello”
的隐式空字符,我会说相反的(添加它)是不清楚的,并且肯定不是你想要的99%的时间。另一方面,如果你想向字符串中添加
'\0'
,只需像缓冲区一样附加它:

char buffer[] = "Hello";
s.append(buffer, sizeof(buffer));
或者(甚至更好)完全删除字符数组和以null结尾的字符串,并使用C++风格的替换,如
std::string
作为NTS替换,
std::vector
作为连续缓冲区,
std::vector
作为带指针替换的动态数组,以及
std::array
(C++11)作为标准C数组替换


另外,(正如@AdamRosenfield在注释中提到的),添加
“hello”后的字符串"
实际上有20个字符,这可能只是因为您的终端不打印空字符。

std::string更像是字符的容器,而\0是字符。作为一个真实的示例,请查看Windows中的函数。lpEnvironment参数采用以空结尾的字符串组成的以空结尾的块(即
A=1\0B=2\0C=3\0\0
)。如果你正在构建一个块,使用std::string是很方便的。

std::string
不是以空结尾的字符串。“字符串的完整性被破坏”?
std::string
的全部要点是你从1970年起就没有任何限制,例如“不能包含
\0
”。如果您检查了标准,发现这是正确的行为,您的问题是什么?请将
std::string
视为一种字符容器,其中包含大量字符串功能。在
+=“hello”
行之后,字符串不是5个字符的字符串
“hello”
,正如您的注释所示。字符串实际上是
“\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0 hello”
,但您的终端可能无法打印ASCII NUL字符,因此它似乎只打印
“hello”
。但是如果您将程序的输出保存到一个文件中,并检查原始文件数据,您将看到其中的15个NUL字符。还有一个更复杂的问题是
c_str()< /COD>确实返回空终止的字符串,这意味着STD::String实现必须使用长度字段和空终止符。@ Rordy:是的,如果在中间做零,显然不能用它作为CXString()。以传统的C风格字符串方式进行字符串。你不能既吃蛋糕又吃蛋糕。实际上,直到你调用
C_str()为止,我不认为实现必须在最后加上一个零。但是我猜想大多数实现都是因为它比在重新分配字符串时更容易做到这一点,并且当您在<代码> CyString()/<代码>中遇到一个零时,尤其是在C++ 11中,代码< >
定义为从字符串返回实际数据,而不是二次副本。