2015-01-29 3 views
1

Есть много вопросов о промывочном стандартном вводе, шахты не о том, чтобы очистить его, а о значении следующей функции:Почему пустой STDIN с EOF

while((c = getchar()) != '\n' && c != EOF); 

Я пытаюсь думать о сценарии и почему как нам понадобится EOF в этой функции для опорожнения stdin? Пользователь вводит что-то и нажимает enter, и мы освобождаем буфер до тех пор, пока не найдем enter, куда входит EOF?

Спасибо

Edit: Большое спасибо за первый ответ и второй комментарий, который отвечает на мой вопрос и полностью меня удовлетворяет.

Кроме сценария, в котором мы передаем наш ввод из файла, где у нас есть реальный EOF, который в значительной степени ответил на мой вопрос, я до сих пор не понимаю, зачем нам нужен EOF в любом другом сценарии для такой функции. пользователь может вызывать только EOF в начале строки в терминале, поэтому его нельзя использовать для опорожнения буфера.

+2

Вы не очищаете 'stdin' с' EOF', этот код просто читает все символы из 'stdin' и отбрасывает их, это зависит от того, где этот код, я имею в виду контекст. Если вы, например, используете 'scanf()' для чтения значения и введите допустимое значение, за которым следуют пробелы, этот код удалит все пробелы из входного буфера. –

+0

Рассмотрите сценарий, в котором оболочка подключает входные данные из файла в STDIN вашего приложения ... –

+0

Для полноты вам может потребоваться опубликовать тип 'c', который должен быть' int', а не 'char'. – chux

ответ

5

Если пользователь вставляет Ctrl-D (в Linux/OS X) или Ctrl-Z (в Windows), вы получаете EOF из stdin. Кроме того, стандартный ввод может быть перенаправлен из файла - в этом случае вы получаете «реальный» EOF.

В обоих случаях без этого проверьте, что цикл будет продолжаться вечно, ожидая новой строки, которая никогда не придет (вставьте здесь меланхолическую музыку).

+0

Спасибо, кроме сценария, где мы передаем наш вход из файла, где у нас есть реальный EOF, который в значительной степени ответил на мой вопрос, я до сих пор не понимаю, зачем нам нужен EOF в любом другом сценарии для такой функции. пользователь может вызывать только EOF в начале строки в терминале, поэтому его нельзя использовать для опорожнения буфера. – Mcs

+0

@Mcs, * пользователям * может не понадобиться отправлять EOF, но * ваша программа * должна учитывать возможность ее получения. –

+0

@Mcs: это полностью зависит от эмулятора терминала; на моей машине Linux, xterm, Konsole и все виртуальные консоли с радостью принимают первую промежуточную строку Ctrl-D как флеш stdin, а следующую (все еще в той же строке), что и EOF. –

4

Ваш код не «смывается» stdin. Все, что он делает, это поиск ближайшего '\n', или конец ввода, в зависимости от того, что наступит раньше.

Вы можете получить EOF в нескольких ситуациях:

  • Конечный пользователь нажимает комбинацию, которая закрывает stdin, а это означает, что следующая попытка чтения будет возвращать EOF или
  • Вы попали фактические конечные когда вход перенаправляется через специальные для ОС средства доступа к файлу вместо использования консоли, например a.out <data.txt
  • Ошибка чтения в середине доступа к входному потоку вашей программы.

Причины, по которым вы можете это сделать, могут быть разными, но чаще всего они очищают остатки от какого-либо предыдущего недопустимого ввода.

+0

в порядке, этот код сбрасывает stdin: do c = getchar(); while (c! = EOF && c! = '\ n'); второй, когда я нажимаю кнопку управления + z в окнах ничего не происходит, если я не пишу программу, в которой говорится, что что-то должно произойти, и для этого мне нужно читать EOF в любом случае – Mcs

+0

@Mcs Это вещь с 'EOF', она не приходит к вам, пока вы не попросите об этом. Нажатие Ctrl + z не отправляет «EOF», а просто сообщает консоли о закрытии входного потока. На данный момент больше ничего не может попасть в поток, но персонажи, которые уже там, останутся там. Поэтому, если вы введете «привет» перед нажатием Ctrl + z, и программа считывает первые три символа, остальные два символа останутся в буфере для вашей программы для чтения. – dasblinkenlight

+0

Может захотеть добавить третью причину получения «EOF': ошибка чтения. – chux

1

В заявлении вы представите считывает оставшуюся часть текущей строки из stdin и отбрасывает его, заканчивается ли строка с символом новой строки ('\n') или в конце потока (EOF). Как отмечает dasblinkenlight, это не то, что условно называют «флешем».

getchar() возвращается EOF в конце потока или по ошибке, и EOF != '\n', поэтому без EOF проверки, что оператор будет цикл бесконечно, если она достигает конец потока.

Отнюдь не обязательно, что последняя строка ввода будет завершена с использованием новой строки. На самом деле вы можете утверждать, что последняя строка потока - это тот, который завершен в конце потока, поэтому последняя строка: never завершена, но может содержать нулевые символы.

+0

, но зачем пользователю вводить что-то, а затем вводить control-z, это просто не имеет смысла для меня , пользователь может ТОЛЬКО вызвать EOF в начале строки, так или иначе, я не понимаю, может быть, я до сих пор не понимаю, как работает EOF – Mcs

+1

@Mcs Это неверно, что конечные пользователи могут «вызывать EOF в начале строка ", вы можете нажать ее в любое время, прямо посредине слова. – dasblinkenlight

+0

@Mcs, dasblinkenlight описал два сценария, в которых программа может столкнуться с 'EOF' на' stdin'. Третий, связанный с ним, возникает, когда вывод одной программы «подается» на вход другого. В любом случае, для плохой практики для программы предполагается, что ее входные данные будут принимать только желаемую форму. Устойчивая программа учитывает все возможности. –

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