文件中的"^@"代表什么意思?

21

代码:

int fd;
fd = open("fruit", O_WRONLY);
write(fd, "apple", sizeof("apple"));
close(fd);

我使用以下方式进行编译:

$ gcc test.c -o test

并运行为

$ ./test   

然后我打开fruit文件,我在文件中看到以下内容:

apple^@

^@ 代表什么意思?


7
sizeof("apple")改为strlen("apple")以消除它。 - mcleod_ideafix
1
在这些情况下,使用十六进制转储程序来确保文件内容 http://www.theunixschool.com/2011/06/3-different-ways-of-dumping-hex.html - leonbloy
2个回答

41

这是空字符代码'\0'。像vi这样的编辑器将其显示为^@

sizeof("apple")返回6,因为它包括用于终止字符串的空字符。


39

^@是ASCII NUL的常见可打印表示方式。这与@字符相同,只是移除了一些位:

@ = 0100
^@ = 0

并且它与C语言中的字符串终止符'\0'相同。由于它是字符串终止符,你无法从printf或其相关函数中看到它,但是你可以使用块状的write轻松创建它。例如,您可以编写以下代码:

and it is the same as '\0' (the string terminator in C). 因为它是字符串终止符,你无法从printf或其相关函数中看到它,但是你可以使用块状的write轻松创建它。例如,您可以编写:

write(fd,"apple\0orange",sizeof("apple\0orange"));

并看到了

apple^@orange^@

因为在C语言中,每一个以双引号包含的字面量都有一个被计入其大小的结尾字符串终止符。如果您想要写出不带终止符的字符串,可以这样做:

const char *s = "apple";
write(fd,s,strlen(s));

因此,通过确保两者是同一项,消除了示例中的两个问题:(a)不正确的长度和(b)可能使用不一致的字符串内容和长度。请参见Sizeof字符串文字以获取有关(a)的一些评论。

NUL是32个ASCII控制字符之一,其值范围从0到31,称为C0控件。所有这些ASCII控制字符通常以这种方式显示(可打印形式),使用对应于将64(0100)添加到控制字符值的字符。

ASCII DEL是127(0177)。 将其显示为^?是一个特殊情况,比其他ASCII控制字符更近。例如,X / Open terminfo(curses)未定义此字符的可打印形式,尽管它为其他字符定义了。与其他ASCII控制字符不同,DEL通过将所有(七个)位组合到字符中来形成。

ASCII当然是7位代码。许多其他代码已经开发出来; ASCII对应于POSIX可移植字符集,因此经常遇到。

可以轻松地通过网络搜索找到ASCII字符表。这些表(或其附带的讨论)中的大多数都会偏离错误信息。这里是一个相当真实的页面链接,名为ASCII字符集。 它声明

控制键从修改它的键的值中减去64。

但是,如果该键是来自集合@AB等,则该语句仅正确。 如果将其应用于其他键,则结果可能有趣但不实用。 相反,在C程序中,您将执行逻辑掩码操作,例如,

ch = ch & 037;

获得0到31范围内的字符。


1
DEL也可以显示为^?(在这种情况下,0x40位被清除而不是设置)。 - deltab
考虑在第四段中添加“因为没有定义的可打印形式” :) - Jongware
1
顺便提一下——Unicode确实定义了控制字符的符号:␀ ␡(但您的浏览器可能无法显示它们)。 - Tom Blodget
2
我的浏览器显示了你评论中的内容,但它们是小型大写字母,并且只有因为我知道你的意图,所以才可读。 - Thomas Dickey

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