#c #buffer
Вопрос:
У меня есть вопрос общего понимания! Вот мой код:
#include <stdio.h> #include <unistd.h> #include <stdlib.h> #include <cstring> int main() { // read user input char input[64] = {0}; read(0, input, 64); printf("You've entered "); printf(input); char newbuf[128]; char smallbuf[8]; // copy into smallbuf 8 bytes of input memcpy(smallbuf, input, 8); // send smallbuf of 8 bytes as string into newbuf sprintf(newbuf, "%s", smallbuf); // print newbuf printf(amp;newbuf[0]); return 0; }
Поведение, которое я получаю с 7 символами, в порядке, оно выводит 7 символов:
$ gcc a.cpp -o a.out amp;amp; ./a.out 1234567 You've entered 1234567 1234567 1234567
Но с 8 символами он печатает их намного больше, и мне интересно, почему он это делает:
$ gcc a.cpp -o a.out amp;amp; ./a.out 12345678 You've entered 12345678 1234567812345678
Спасибо, что объяснили мне! 🙂
Комментарии:
1. строки имеют значение null, чтобы отметить конец. Если вы не скопируете значение null, строка не будет завершена
2. @stark означает ли это, что если мы запишем n-1 символов в качестве входных данных, то, когда мы нажмем enter, будет скопирован нулевой символ завершения, но когда мы напишем ровно n символов, где n-размер байтов для копирования, мы опустим нулевой символ завершения, потому что мы перезаписываем его последним символом ввода?
3. При вызове нет завершающего нулевого символа
read
. Вы обошли эту проблему, инициализировав свойinput
массив со всеми 0, но затем проблема поднимается, когда вы пишете вsmallbuf
иnewbuf
.4. Кроме того, пожалуйста, никогда не пишите такие вещи, как
printf(amp;newbuf[0])
. Если пользователю случится ввести строку, содержащую один%
или два знака, произойдут сумасшедшие вещи! Всегда печатайте строки с помощьюprintf("%s", amp;newbuf[0])
, илиputs(amp;newbuf[0])
. (И в этом случае вам может сойти сprintf("%s", newbuf)
рук , илиputs(newbuf)
. )5. memcpy не знает о строках. Взгляните на веревочку. функции h.
Ответ №1:
Код пытается напечатать массив символов, как если бы это была строка, приводящая к неопределенному поведению. smallbuf[]
определенно не содержит нулевого символа, поэтому это не строка.
"%s"
ожидает соответствующий указатель на строку.
Либо учитывайте нулевой символ
char smallbuf[8 1]; memcpy(smallbuf, input, 8); smallbuf[8] = ''; printf("%s", smallbuf);
или ограничьте выход с определенной точностью. Это выводит массив символов до N символов или нулевой символ.
char smallbuf[8]; memcpy(smallbuf, input, 8); printf("%.8s", smallbuf);
Аналогичная проблема относится и к printf(input);
Не кодируйте printf(input);
, так как это может привести к неопределенному поведению, когда input[]
содержит a %
.
// printf(input); printf("%s", input);
Лучший код проверил бы возвращаемое значение read(0, input, 64)
.