scanf
понятия не имеет, насколько велик целевой буфер.Все, что он знает, это начальный адрес буфера.C не проверяет границы, поэтому, если вы передадите ему адрес буфера размером 2 символа и введете строку длиной 10 символов, scanf
запишет эти дополнительные 8 символов в память после конца буфера,Это называется переполнением буфера, которое является распространенным вредоносным программным средством.По какой-то причине шесть байтов, следующих сразу за вашим буфером, не являются «важными», поэтому вы можете ввести до 8 символов без видимых вредных последствий.
Вы можете ограничить число символов, читаемых в вызове scanf
, включив явную ширину поля в спецификатор преобразования:
scanf("%2s", A);
, но вам все равно нужно убедиться, чтоцелевой буфер достаточно велик, чтобы вместить эту ширину.К сожалению, невозможно динамически указать ширину поля, как в printf
:
printf("%*s", fieldWidth, string);
, поскольку %*s
означает что-то совершенно другое в scanf
(в основном, пропуститьпо следующей строке).
Вы можете использовать sprintf
для построения строки формата:
sprintf(format, "%%%ds", max_bytes_in_A);
scanf(format, A);
, но вы должны убедиться, что буфер format
достаточно широк для хранения результата и т. Д., И т. Д.и т. д.
Именно поэтому я обычно рекомендую fgets()
для интерактивного ввода.