21

代码:

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

我用它编译

$ gcc test.c -o test

并运行为

$ ./test   

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

apple^@

是什么^@意思?

4

2 回答 2

41

它是空字符代码'\0'。某些编辑器(如vi)将其显示为^@.

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

于 2015-05-17T00:31:22.270 回答
39

^@是 ASCII NUL 通常以可打印形式表示的方式。@这与删除了一些位的字符相同:

@ = 0100
^@ = 0

它与'\0'(C中的字符串终止符)相同。因为它是字符串终止符,所以您不会从printf它或其相关函数中看到它,但您可以使用面向块的write. 例如,你可以写

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

并看到

apple^@orange^@

因为C 中的每个双引号文字都有一个尾随字符串终止符,该终止符计入其大小。如果您打算编写没有终止符的字符串,您可以这样做:

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

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

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

ASCIIDEL为 127 (0177)。将其显示为^?比其他 ASCII 控制字符更新的特殊情况。例如,X/Open terminfo (curses) 没有为这个字符定义一个可打印的形式,尽管它为其他字符定义了一个可打印的形式。与其他 ASCII 控制字符不同,DEL它是通过对字符的所有(七)位进行“或”运算而形成的。

当然,ASCII 是 7 位代码。开发了许多其他代码;ASCII 对应POSIX 可移植字符集,所以经常遇到。

通过网络搜索很容易找到 ASCII 字符表。这些表格中的大多数(或其随附的讨论)都转向了错误信息。这是一个链接到一个合理的事实页面,标题为ASCII Character Set。它指出

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

@但是,仅当键是 set 、A、等中的键之一时,该语句才是正确的B。如果将其应用于其他键,结果可能很有趣但没有用。相反,在 C 程序中,您将执行逻辑屏蔽,例如,

ch = ch & 037;

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

于 2015-05-17T00:32:49.727 回答