Другие ответы совершенно правильны в решении вашей проблемы. Я хотел добавить немного предыстории.
Строка символов C - это адрес непрерывной последовательности в памяти байтов, содержащих значения символов - ie a char*
. Причина, по которой ваши выходные данные содержат причудливые символы, заключается в том, что вы сказали printf
обрабатывать адрес памяти, указывающий на имя животного, как один символ.
Если мы напишем такой код,
#include <stdio.h>
int main() {
char *str = "blah blah blah";
printf("%c\n", str);
}
Вменяемая компиляция предупредит вас, что вы. приведение вашего адреса в неподходящий тип:
$ gcc -o ct t.c
t.c:5:18: warning: format specifies type 'int' but the argument has type
'char *' [-Wformat]
printf("%c\n", str);
~~ ^~~
%s
1 warning generated.
Следует ожидать проблем с любым написанным вами кодом, который выдает предупреждения при компиляции. Код все еще может завершить компиляцию sh, но это не значит, что он будет работать правильно. Немедленно исправьте все предупреждения компилятора - C - сложный язык, и если вы проигнорируете предупреждения компилятора, вы, скорее всего, получите непреднамеренное поведение, весьма вероятно в, казалось бы, не связанных частях кода.
В моем случае я получаю нечто подобное, потому что первый байт адреса строки не является допустимой печатаемой последовательностью символов:
$ ./ct
�
Изучение вывода в шестнадцатеричном формате помогает нам увидеть \n
(значение ascii 0a
в моем окружении, также называемое "newlline", также называемое "перевод строки" в ascii). Непосредственно после этого это шестнадцатеричное значение значения вывода «% c» - 0xa2
. Так как это не входит в стандартную 7-битную таблицу ascii, и мой терминал настроен на Unicode, этот символ недопустим и доступен для печати, поэтому отображается символ �
.
$ ./ct | hexdump
0000000 a2 0a
0000002
Если мы изменим %c
на %s
, мы больше не получим предупреждение компилятора, и код работает нормально.
$ cat t.c
#include <stdio.h>
int main() {
char *str = "blah blah blah";
printf("%s\n", str);
}
$ gcc -o ct t.c
[ no output ]
$ ./ct
blah blah blah
$ ./ct | hexdump
0000000 62 6c 61 68 20 62 6c 61 68 20 62 6c 61 68 0a
000000f
Я включил hexdump на случай, если вы захотите увидеть, как моя строка blah blah blah\n
показывается в байтовом выражении.