Каждый раз, когда я делаю scanf перед fgets, fgets инструкция пропускается. Я приехал через эту проблему в C++, и я помню, что имел к, имел некоторый instrcution, который очистит буфер stdin или что-то как этот. Я предполагаю, что существует эквивалент для C.Что это?
Спасибо.
Готов поспорить, это из-за того, что \ n застрял во входном потоке.
См. Один из следующих вопросов:
Я не могу очистить стандартный ввод.
Как мне выполнить очистку STDIN здесь?
scanf () вызывает бесконечный цикл
или этот ответ .
Также: Почему бы не использовать scanf () .
P.S. fgets ()
- это функция, а не инструкция.
Функция fgets ()
после вызова scanf ()
является , вероятно, 1 не пропускается. Это , вероятно, 1 немедленно возвращается, обнаружив новую строку во входном потоке.
Вызов scanf ()
перед fgets ()
почти всегда приводит к тому, что scanf ()
оставляет неиспользуемую новую строку ( '\ n'
) во входном потоке, что и ищет fgets ()
.
Чтобы смешать scanf ()
и fgets ()
, вам необходимо удалить новую строку, оставшуюся после вызова scanf ()
из входной поток.
Одним из решений для сброса stdin (включая новую строку) может быть что-то вроде следующего:
int c;
/* discard all characters up to and including newline */
while ((c = getchar()) != '\n' && c != EOF);
1 - Трудно быть уверенным, не увидев фактический код.
Или, как Джерри Коффин предложил в своем комментарии ниже, вы можете использовать scanf ("% * [^ \ n]");
. Директива "% * [^ \ n]"
предписывает scanf ()
сопоставлять элементы, не являющиеся символами новой строки, и подавлять присвоение результата преобразования.
/* match up to newline */
scanf("%*[^\n]");
/* discard the newline */
scanf("%*c");
Из http://c-faq.com/stdio/gets_flush1.html :
Исходный
scanf ()
с«% * [^ \ n] ”
либо съест все до новой строки, но не включая ее, либо завершится ошибкой. Последующий«% * c»
(или старый добрыйgetchar ()
) будет использовать новую строку, если она была.Последнее «если» тоже имеет значение: возможно, пользователь подал сигнал EOF.В этом случае
getchar ()
илиscanf ("% * c")
могут - это решение остается за людьми, которые пишут ваш компилятор - либо немедленно вернуть EOF, или вернитесь к пользователю для получения дополнительных сведений. Если разработчики выберут последнее, пользователю, возможно, придется щелкнуть «закончить это дело» (^ D, ^ Z, кнопка мыши, переключатель на передней панели или что-то еще) еще раз. Это как минимум раздражает.
Или, как Крис Додд предложил в своем комментарии ниже, вы можете использовать scanf ("% * [^ \ n]% * 1 [\ n]");
. Директива "% * [^ \ n]% * 1 [\ n]"
инструктирует scanf ()
сопоставить элементы, не являющиеся символами новой строки, а затем сопоставить одну новую строку и запретить присвоение результаты конвертации.
/* match and discard all characters up to and including newline */
scanf("%*[^\n]%*1[\n]");