Ответ 1
Это код нулевого символа '\0'
. Некоторые редакторы, такие как vi, отображают его как ^@
.
sizeof("apple")
будет возвращать 6, потому что он содержит нулевой символ, используемый для завершения строк.
код:
int fd;
fd = open("fruit", O_WRONLY);
write(fd, "apple", sizeof("apple"));
close(fd);
Я скомпилирую его с помощью
$ gcc test.c -o test
и выполняться как
$ ./test
Затем я открываю файл fruit
, и я вижу следующее в файле:
apple^@
Что означает ^@
?
Это код нулевого символа '\0'
. Некоторые редакторы, такие как vi, отображают его как ^@
.
sizeof("apple")
будет возвращать 6, потому что он содержит нулевой символ, используемый для завершения строк.
^@
- это способ, которым 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) неправильную длину и (б) возможно использование несогласованного содержимого строки и длины, гарантируя, что оба являются одним и тем же элементом. См. Размер строки литерала для некоторых комментариев по (a).
NUL
является одним из 32 управляющих символов ASCII, значения которых варьируются от 0 до 31, называемые C0-элементами управления.
Все эти управляющие символы ASCII обычно отображаются таким образом (для печатаемой формы), используя символ, соответствующий добавлению 64 (0100) к значению контрольного символа.
ASCII DEL
- 127 (0177). Отображение его как ^?
- это особый случай, который является более поздним, чем другие управляющие символы ASCII. Например, X/Open terminfo (curses) не определяет печатную форму для этого символа, хотя для других. В отличие от других управляющих символов ASCII, DEL
формируется путем OR'ing всех (семи) бит в символ.
ASCII - это 7-битный код, конечно. Было разработано много других кодов; ASCII соответствует переносной набор символов POSIX, поэтому он часто встречается.
Легко найти таблицы символов ASCII с веб-поиском. Большинство этих таблиц (или их сопровождающее обсуждение) отклоняются от дезинформации. Вот ссылка на достаточно фактическую страницу, озаглавленную Набор символов ASCII. В нем указано
Ключ управления вычитает 64 из значения ключей, которые он изменяет.
Однако утверждение справедливо только в том случае, если ключ является одним из значений из набора @
, A
, B
и т.д. Если вы примените это к другим ключам, результаты, возможно, интересны, но не полезны, Скорее, в программе на C вы должны сделать логическую маскировку, например,
ch = ch & 037;
чтобы получить символ в диапазоне от 0 до 31.