在C++字符串中,'\0'和"\0"之间有什么区别?

4
我尝试以两种方式在字符串中添加空终止符(\0)。 一种是使用'\0',另一种是使用"\0",而且在这两种情况下,我得到了不同的输出结果:
#include <iostream>
#include <string.h>
using namespace std;

int main()
{
    string test1 = "";
    test1 += "\0";
    cout << test1.size() << endl;
    
    string test2 = "";
    test2 += '\0';
    cout << test2.size() << endl;
}

我正在获取输出
0
1

有人可以解释一下为什么字符串将'\0'作为字符而不是空终止符吗?如果我打印test1test2,它会打印一个空字符串。

4
一个('\0')是一个"字符字面量",另一个("\0")是一个"字符串字面量"。 - undefined
2
C++ 字符串不是以空字符结尾的,如果需要的话,你可以在字符串后面添加一个空字符 ('\0')。而 C 风格的字符串是以空字符结尾的,所以 "\0" 表示一个长度为零的空字符串。 - undefined
1
你不需要这些东西。 - undefined
2
我尝试以两种方式在字符串中添加空终止符(\0)。-- 为什么?std::string可以通过std::stringlengthsize成员函数知道自己的长度,不需要任何空终止符。你似乎对C风格的字符串感到困惑,因为在C风格的字符串中,空终止符是必需的。 - undefined
1
@teapot418 — ”\0” 是一个包含两个字符的字符串字面量,都是 '\0'。一个空字符串只是 ””;它只包含一个字符,即 '\0' - undefined
1个回答

10
'\0' 是一个单个字符。一个值为0的char。
"\0" 是一个包含两个字符的数组。一个值为{ 0, 0 }的const char[2](第一个是代码中指定的字符串字面量,第二个是编译器添加的所有字符串字面量的空终止符)。
当你使用test2 += '\0';时,这将一个字符传递给string对象以追加到它。调用的函数是std::string::operator+=(char)。
当你使用test2 += "\0";时,这将指向数组第一个元素的指针传递给string对象,调用std::string::operator+=(const char*)。这被解释为一个C字符串,它不能包含嵌入的空字符。当你只有一个指针时,无法区分""和"\0",因为两种情况下的第一个字符都是'\0',看起来像是字符串的结尾。
如果你想使用嵌入的空字符,你必须单独传递大小。这可以通过std::string::append()来实现,例如:
// ptr+size
test2.append("\0", 1);

// iterator pair
const auto& str = "\0";
test2.append(std::begin(str), std::end(str)-1);  // (-1 for the extra nul terminator)

或者,使用一个带有大小的string_view
using namespace std::literals::string_view_literals;
test2 += "\0"sv;
// "\0"sv.size() == 1

如果我在字符串中添加"\0",它会被视为空终止符,导致字符串被认为是空的。然而,如果我添加'\0',似乎它并不将其视为空字符。即使我使用test2.empty(),它返回false,表示非空。然而,当我打印test2时,却打印出空字符串,给人一种字符串是空的印象,尽管它有内容。 - undefined
2
@RahulKumawat std::string不是以空字符结尾的,所以向其中添加空字符只会添加一个字符。你用于打印字符串的方法可能只是不打印空字符。 - undefined
@RahulKumawat 当你打印字符串时,你希望字符\0以何种方式显示呢?虽然我曾经使用过一些终端设备,其中控制字符有一个表示(以非常小的字母对角线写着“nul”),但大多数终端设备会简单地忽略它。 - undefined

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接