инструкции по fgets пропускаются. Почему?

Каждый раз, когда я делаю scanf перед fgets, fgets инструкция пропускается. Я приехал через эту проблему в C++, и я помню, что имел к, имел некоторый instrcution, который очистит буфер stdin или что-то как этот. Я предполагаю, что существует эквивалент для C.Что это?

Спасибо.

5
задан nunos 25 May 2010 в 17:44
поделиться

2 ответа

Готов поспорить, это из-за того, что \ n застрял во входном потоке.

См. Один из следующих вопросов:

Я не могу очистить стандартный ввод.
Как мне выполнить очистку STDIN здесь?
scanf () вызывает бесконечный цикл

или этот ответ .

Также: Почему бы не использовать scanf () .

P.S. fgets () - это функция, а не инструкция.

5
ответ дан 14 December 2019 в 04:31
поделиться

Функция 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]");
3
ответ дан 14 December 2019 в 04:31
поделиться
Другие вопросы по тегам:

Похожие вопросы: