【问题标题】:Difference between null terminated char (\0) and `^@`以空字符结尾的字符 (\0) 和 `^@` 之间的区别
【发布时间】:2025-12-29 17:00:06
【问题描述】:

我的代码是这样的:

#include <iostream>
using std::cout;
using std::endl;

int main(int argc, char *argv[])
{
    cout << (int)('\0') << endl;
    cout << (char)(0) << endl;
    return 0;
}

我希望在终端中看到这样的:

$ test-program
0

$ 

然而,我看到的是这样的:

$ test-program
0
^@
$

让我感到困惑的是,我认为'\0' 可以转换为0。并且0 也可以转换为\0。我预计会看到一个空字符,后跟一个endl,但结果有点奇怪,比如^@

有人对此有想法吗?

【问题讨论】:

  • 我在 Windows 中得到了预期的结果(使用 MinGW gcc 编译)。
  • 使用| hexdump -C 查看十六进制输出。通过这种方式,您可以确保 您的程序 执行您期望它执行的操作,因此它的 终端 的行为与(您)预期的不同。
  • 这是 c++,然后类型很重要。在第一种情况下,必须显示整数 0,然后将 0 转换为测试“0”。在第二种情况下,它是一个真正的字符 0,它实际上是一个字符 0。.test-programm > 结果。将 emacs 与 --hexl-mode 一起使用,它将确认这一点。第二点是可以变化的字符 0 的终端显示,在您的情况下,字符 0(通常不应该显示,因为在 C 中它以字符串结尾)将显示为 ^@.

标签: c++ c arrays string char


【解决方案1】:

如果您正在查看终端的输出,您不知道是您的程序没有按预期运行,还是只是您的终端模拟器。

在 UNIXoid 系统上,使用 ./myProgram | hexdump -C 查看十六进制输出。这样你就可以确保你的程序做你期望它做的事情,所以它是终端,它的行为不像(你)预期的那样:

00000000  30 0a 00 0a                                       |0...|
00000004

如果您看到与我相同的输出,您实际上是在打印零'0'、换行符'\n'、空值'\0'、换行符'\n'。因此,在这种情况下,您的程序会按照您的预期运行。

您可能想尝试不同的终端模拟器或设置。

【讨论】:

    【解决方案2】:

    ^@ 就是您的终端模拟器呈现'\0' 的方式。

    【讨论】:

      【解决方案3】:

      ^@ 是空字符的常见表示形式。类似地,^A 用于表示序数值为 1 的字符,^G 用于表示序数值为 7(铃)的字符,^M 用于表示序数值为 13 的字符(回车)。

      cout << (char)0
      

      只是打印字符表示,而不是整数表示

      【讨论】:

        【解决方案4】:

        如果您将0 转换为char,它不会生成'0',但'\0' -- 请记住从整数类型转换为char 会使用该ASCII 代码创建一个char . 所以基本上,第二行输出一个空字符(ASCII 0)。

        如果您想输出一个'0' 字符,则需要执行类似(char) 48 的操作,因为 48 恰好是字符 0 的 ASCII 值。

        【讨论】:

        • OP 知道他正在打印空字符,或者至少我认为他从他写问题的方式来看是这样做的。
        • 那么第一行是错误的,因为在这种情况下它显示的是零整数,这与零字符不同。