getchar() И putchar()
Как было показано в главе 7, функции getchar ( ) и putchar() выполняют ввод и вывод по одному символу за раз. Такой подход может показаться нерациональным. В конце концов, можно легко читать группы, состоящие из нескольких символов, но этот метод вполне вписывается в возможности компьютера. Более того, такой подход лежит в основе большинства программ, имеющих дело с текстом — т.е. с обычными словами. Чтобы напомнить, как работают эти функции, в листинге 8.1 приведен очень простой пример. Здесь всего лишь принимаются символы из клавиатурного ввода и затем отображаются на экране. Такой процесс называется эхо-выводом ввода. В коде применяется цикл while, который завершается при обнаружении символа #.
Символьный ввод-вывод и проверка достоверности ввода 295
Листинг 8.1. Программа echo.с

Со времен появления стандарта ANSI С в языке с использованием функций getchar() и putchar() ассоциирован заголовочный файл stdio.h, потому он и был включен в программе. (Обычно getchar() и putchar() не являются истинными функциями, а определены с применением макросов препроцессора, как будет раскрыто в главе 16.) Выполнение программы приводит к обмену следующего вида:
Здравствуйте. Я хотел бы [enter]
Здравствуйте. Я хотел бы
приобрести #3 мешка картофеля.[enter]
приобрести
После наблюдения за работой этой программы может возникнуть вопрос, почему нужно набирать строку полностью, прежде чем введенные символы будут повторены на экране. Вас также может интересовать, есть ли лучший способ завершения ввода. Использование для завершения ввода специального символа, такого как #, предотвращает его употребление в тексте. Чтобы ответить на эти вопросы, давайте посмотрим, каким образом программы на языке С обрабатывают клавиатурный ввод. В частности, мы выясним, что собой представляет буферизация, и ознакомимся с понятием стандартного входного файла.
Буферы
Если вы запустите предыдущую программу на некоторых более старых системах, то вводимый текст может отображаться на экране немедленно. То есть выполнение этой программы могло бы дать примерно такой результат:
ЗЗддррааввссттввууййттее.. ЯЯ ххооттеелл ббыы[епбег]
ппррииооббрреессттии #
Такое поведение является исключением. В большинстве систем ничего не произойдет до тех пор, пока не будет нажата клавиша , как в первом примере запуска. Немедленный эхо-вывод вводимых символов на экране представляет собой пример небуферизированного (или прямого) ввода, при котором набираемые символы немедленно становятся доступным для ожидающей их программы. С другой стороны, задержанный эхо-вывод иллюстрирует буферизированный ввод, когда введенные символы накапливаются и хранятся во временной области, называемой буфером. Нажатие клавиши делает блок набранных символов доступным для программы. Эти две разновидности ввода сравниваются на рис. 8.1.
Зачем иметь буферы? Во-первых, передача нескольких символов в виде блока является менее затратной по времени, чем отправка символов по одному. Во-вторых, в случае опечатки можно воспользоваться средствами корректировки, поддерживаемыми клавиатурой, и исправить опечатку. Затем после финального нажатия программе будет передана исправленная версия.

Глава 8
С другой стороны, небуферизированный ввод желателен для некоторых интерактивных программ. Например, в играх требуется, чтобы каждая команда выполнялась сразу же после нажатия клавиши. Таким образом, и буферизированный, и небуферизированный ввод имеют свои применения.
Существуют два вида буферизации — полностью буферизированный ввод-вывод и построчно буферизированный ввод-вывод. При полностью буферизированном вводе буфер сбрасывается (его содержимое отправляется в место назначения), когда он полон. Буферизация такого вида обычно происходит при файловом вводе. Размер буфера зависит от системы, но наиболее распространены значения 512 и 4096 байтов. В случае построчно буферизированного ввода-вывода буфер сбрасывается всякий раз, когда появляется символ новой строки. Клавиатурный ввод обычно является построчно буферизированным, так что нажатие вызывает сброс буфера.
Читать дальше