Разбивка scanf("%*[^\n]%*c")
:
%*[^\n]
сканирует все до \n
, но не сканирует в \n
. Звездочка (*
) сообщает ему отменить все, что было отсканировано. %*c
сканирует один символ, который в этом случае будет \n
слева %*[^\n]
. Звездочка указывает scanf
отказаться от отсканированного символа. Оба %[
и %c
являются спецификаторами формата. Вы можете видеть, что они делают здесь . Звездочки в обоих спецификаторах указывают scanf
, а не на сохранение данных, считываемых этими спецификаторами формата.
В вашем случае этот scanf
удаляет stdin
, когда пользователь вводит неверный ввод.
Лучше использовать
scanf("%*[^\n]");
scanf("%*c");
, чтобы очистить stdin
. Это связано с тем, что в первом случае (одиночный scanf
), %*[^\n]
будет терпеть неудачу, когда первым подлежащим сканированию символом является символ \n
, а остальная часть строки формата scanf
будет пропущена, что означает что %*c
не будет функционировать и, таким образом, \n
с входа все равно будет во входном потоке. В этом случае это произойдет не так, как даже когда первый scanf
не будет выполнен, второй будет выполняться, поскольку они являются отдельными операторами scanf
.