C++ 当字符改变时,为什么这个std::字符串的大小会改变?

C++ 当字符改变时,为什么这个std::字符串的大小会改变?,c++,string,escaping,C++,String,Escaping,我有一个问题,字符串的大小会受到'\0'字符的影响。我找遍了所有的地方,仍然找不到答案 下面是片段 int main() { std::string a = "123123\0shai\0"; std::cout << a.length(); } 其中,同一个程序使用不同的字符串,使用数字代替字符 int main() { std::string a = "123123\0123\0"; std::cout << a.length(); } 引擎盖下到

我有一个问题,字符串的大小会受到
'\0'
字符的影响。我找遍了所有的地方,仍然找不到答案

下面是片段

int main()
{
  std::string a = "123123\0shai\0";
  std::cout << a.length();
}
其中,同一个程序使用不同的字符串,使用数字代替字符

int main()
{
  std::string a = "123123\0123\0";
  std::cout << a.length();
}

引擎盖下到底发生了什么?
'\0'
字符的存在如何改变行为?

在字符串(或字符)文本中使用的序列
\012
是八进制转义序列。它是与换行符(
'\n'
)对应的八进制数
12

这意味着您的第二个字符串实际上等于
“123123\n3\0”
(加上实际的字符串文字终止符)

如果您尝试打印字符串的内容,则会非常清楚


八进制序列的长度为一到三位,编译器将使用尽可能多的数字。

如果您在上检查颜色,您将看到
\012
具有不同的颜色。这是因为这是一个用八进制写的单个字符。

什么使八进制序列在字符串中停止?@Raw-序列的长度或不能是八进制数字的字符。与
\0shai
中的s类似。是否可以在\0后面创建数字(0-7)的文字?只有“<代码>”/“0”+“12”< /代码>(或者甚至这也不行)“SaleWekWin——如果你不想形成一个最大长度八进制序列,比如<代码>”12345“\ 01”“678”< /代码>,在中间有一个带有ASCII 1的字符,那么你可能需要分离这些字符串。编译器将组合相邻的字符串文字。如果使用带有长度参数的字符串构造函数,例如
std::string a(“123123\0shai\0”,12),则还可以获得包含nul字符的std::string。这将包括字符串中的所有12个字符。@slawekwin一个八进制字符最多可以有3位数字,因此
“\0007”
是两个字符:
'\0'
'7'
。答对了!这让我心烦意乱,谢谢你的回答。为什么第一个字符串的长度不是12,第二个字符串的长度不是9?@KyleStrand,因为
std::string
接受
const char*
的ctor将其视为以NUL结尾的字符串。@KyleStrand听起来你需要接触一些C字符串。它们的行为与Java、C#、Python等高级语言中的字符串不同。“空字符”(
\0
)在C字符串中有特殊含义;也就是说,它标志着字符串的结束。@jpmc26我不确定我的注释表明我不理解C字符串是如何工作的。我的困惑在于调用的
std::string
构造函数的行为。请注意,即使在C++98中,
std::string
也可能有一个构造函数接受
const char[]
引用,这将允许它接受字符串文本中嵌入的
null
字符:
std::string(const char(&ch)[N])
。这可能与
std::string(const char*,size\u type count)
构造函数的行为相同。不要在字符串中放入空字符(\0),除非您非常清楚自己在做什么以及为什么要这样做!如果您确实需要以非null结尾的字符串,那么您需要使用
std::literals::string\u literals::operator“s
(C++14)或
std::string(char*,size\u t)
(如果需要,请记住包含最终的null)。请注意,第二个字符串将“shai”(四个字符)替换为“123”(三个字符),因此,即使没有公认答案中提到的八进制序列,也会有差异。。
int main()
{
  std::string a = "123123\0123\0";
  std::cout << a.length();
}
8