2010-05-25 2 views
4

Всякий раз, когда я делаю scanf перед fgets, инструкция fgets пропускается. Я столкнулся с этой проблемой на C++, и я помню, что у меня была какая-то интуиция, которая очистила бы буфер stdin или что-то в этом роде. Я полагаю, что для С. есть эквивалент. Что это такое?Инструкции fgets пропускаются. Почему?

Спасибо.

+7

Код, пожалуйста ..? –

+1

Возможно, вам проще использовать 'fgets' для всех ваших входов, а затем использовать' sscanf', когда вы хотите анализировать значения из строки. –

+0

@Tim Post: Я думал, что для большинства пользователей это будет так просто, что не нашлось нужды. Я думаю, что вопрос достаточно подробный. – nunos

ответ

3

fgets() функции после вызова scanf() является вероятно не получает пропущено. Это возможно , возвращаясь сразу же, найдя новую строку во входном потоке.

Вызов scanf() перед тем fgets() почти всегда приводит к scanf() оставляя неиспользуемый символ новой строки ('\n') во входном потоке, который является именно то, что fgets() высматривает.

Для смешивания scanf() и fgets() вам необходимо удалить новую строку слева по вызову scanf() из входного потока.

Одно решение для смыва стандартного ввода (включая символ новой строки) будет что-то вдоль линий следующее:

int c; 
/* discard all characters up to and including newline */ 
while ((c = getchar()) != '\n' && c != EOF); 

1 - Трудно быть уверенным, не видя реального кода.


Или, как Jerry Coffin предложил в своем комментарии ниже, вы можете использовать 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, кнопка мыши, переключатель на передней панели или что-то еще) за дополнительное время. Это раздражает, если ничего другого.


Или, как Chris Dodd предложил в своем комментарии ниже, вы можете использовать scanf("%*[^\n]%*1[\n]");. Директива "%*[^\n]%*1[\n]" сообщает scanf(), чтобы соответствовать вещам, которые не являются символами новой строки, а затем соответствуют одной новой строке и подавляют назначение результатов преобразования.

/* match and discard all characters up to and including newline */ 
scanf("%*[^\n]%*1[\n]"); 
+2

Вы можете сбросить входной буфер (т. Е. Отбросить до достижения новой строки) немного легче: 'scanf ("% * [^ \ n] ");' –

+1

Вы можете выполнить сброс до и включая новую строку с помощью 'scanf ("% * [^ \ п]% * 1 [\ п]") ' –

Смежные вопросы