Чтение одной строки
Буферы
При выполнении данной программы (любой из двух ее версий), вводимый символ в одних вычислительных системах немедленно появится на экране (эхо-печать), в других же вычислительных системах ничего не происходит до тех пор, пока мы не нажмем клавишу Enter. Первый случай относится к небуферизованному (прямому) вводу, означающему, что выводимый символ оказывается немедленно доступным ожидающей программе. Второй случай служит примером буферизованного ввода, когда вводимые символы собираются и помещаются в некоторой области временной памяти, называемой буфером. Нажатие клавиши Enter приводит к тому, что блок символов, или один символ, становится доступным программе. В нашей программе применяется только первый символ, поскольку функция getchar( ) вызывается в ней один раз.
Зачем нужны буферы?
Во-первых, оказывается, что передачу нескольких символов в виде одного блока можно осуществить гораздо быстрее, чем передавать их последовательно по одному. Во-вторых, если при вводе символов допущена ошибка, мы сможем воспользоваться корректирующими средствами терминала, чтобы ее исправить. И когда мы нажмем клавишу Enter, будет произведена передача откорректированной строки. Однако для некоторых диалоговых программ небуферизованный ввод может оказаться приемлемым. Например, в программах обработки текстов было бы желательно, чтобы каждая команда вводилась, как только мы нажимаем соответствующую клавишу. Поэтому как буферизованный, так и небуферизованный ввод имеет свои достоинства.
Рассмотрим вывод на печать групп символов. Желательно, чтобы в любой момент можно было остановить работу программы. Для этого напишем программу так, чтобы она прекращала работу при получении какого-нибудь специального символа, например "!":
/* ввод-вывод */
/* ввод и печать символов до поступления
завершающего символа */
#include <stdio.h>
#define STOP '!' /*дает символу '!' символическое имя */
main( )
{
char ch;
ch=getchar( ); /***9***/
while(ch != STOP) { /***10***/
putchar( ch); /***11***/
ch=getchar( ); /***12***/
}
}
В данном примере при первом прохождении тела цикла функция putchar( ) получает значение своего аргумента в результате выполнения оператора, расположенного в строке 9. В дальнейшем, вплоть до завершения работы цикла, значением этого аргумента является символ, передаваемый программе функцией getchar, расположенной в строке 12. Цикл while будет осуществлять чтение и печать символов до тех пор, пока не поступит признак STOP.
! Программа, приведенная ниже, делает то же самое, но стиль ее написания лучше отвечает духу языка Си:
/* ввод-вывод */
#include <stdio.h>
#define STOP '!'
main( )
{
char ch;
while ((ch=getchar( )) != STOP) /***8***/
putchar(ch);
}
Одна строка 8 этой программы заменяет строки 9, 10, 12 предыдущей программы.
Усложним пример ввода-вывода:
/* подсчет символов */
#include <stdio.h>
#define STOP '!'
main( )
{
char ch;
/*инициализация счетчика символов 0 */
int count = 0;
while ((ch=getchar( )) != STOP) {
putchar(ch);
count++; /* прибавить 1 к счетчику */
}
printf("\n Всего было прочитано %d символа.\n",
count);
}
Если мы хотим просто подсчитать число введенных символов без отображения их на экране, функцию putchar( ) можно опустить.
Заменим признак окончания ввода данных, используем символ новая строка \n. Для этого нужно переопределить признак STOP:
#define STOP '\n'
Символ новая строка пересылается при нажатии клавиши Enter. Предположим, что мы внесли указанное изменение в программу "подсчет символов", а затем при выполнении ввели следующую строку:
На экране тридцать четыре символа.[Enter]
В ответ на экране появятся следующие строки:
На экране тридцать четыре символа.
Признак, появляющийся в результате нажатия клавиши Enter, не входит в число символов 34, подсчитанных программой, поскольку подсчет осуществляется внутри цикла. Теперь у нас есть программа, которая может прочесть одну строку.