[<<Previous Entry] [^^Up^^] [Next Entry>>] [Menu] [About The Guide]
 Программа просмотра файла - Пример

Эта программа может использоваться для просмотра файла на терминале и
служит другим примером неканонического ввода. Она служит альтернативой
CTRL-S и CTRL-Q, которые, соответственно, задерживают и возобновляют
вывод. В этой программе любая клавиша приостанавливает или
возобновляет вывод на терминал. Например, пробел может использоваться
как переключатель. Этот эффект достигается изменением значения MIN
между нулем и единицей. Эта программа работает так:
13-16     Стандартная библиотечная функция fopen(3) открывает файл для
просмотра.
17   Считывается текущий режим терминального интерфейса.
18   Этот режим сохраняется. Позднее он будет использоваться для
восстановления состояния терминального интерфейса.
19-22     Терминальный интерфейс переключается в режим неканонического
ввода. Кроме того, INTR, QUIT и остальные управляющие символы не
анализируются и эхо выключено. Чтение с терминала будет ожидать в
течении 0.1 секунды, потому что MIN равен нулю, а TIME - 1.
24-33     Этот цикл считывает строки из файла и выводит их на
терминал.
25   read(2) пытается считать с терминала один символ. Так как чтение
возвращает управление немедленно (без ожидания), символ будет
прочитан, только если он был введен до вызова read(2). Непрочитанные
символы накапливаются в буфере. Если считан символ, read(2) возвращает
1 и исполняются операторы 27-31. Если не прочитано ни одного символа,
read(2) возвращает 0. Это называется опросом ввода с терминала.
26-27     MIN установлен в единицу, так что запросы чтения с терминала
будут ждать ввода.
28   Как только символ введен, запрос read(2) удовлетворяется и
возвращает управление.
29-30     Чтение с терминала снова переводится в режим опроса.
34   Восстанавливается исходный режим работы терминала.
После нажатия клавиши для приостановки вывода возникает небольшая
задержка, во время которой выводится несколько лишних строк. Это
связано с буферизацией вывода и низкой скоростью работы терминала.
Как можно прекратить просмотр длинного файла? Например, после чтения в
строке 25, мы можем проверять символ на равенство букве q (quit). Если
был введен этот символ, программа выходит из цикла. Можно даже
использовать символ DEL, так как он читается наравне с остальными
символами.
Файл: lister.c
      ПРОГРАММА ПРОСМОТРА ФАЙЛОВ - ПРИМЕР НЕКАНОНИЧЕСКОГО ВВОДА

 1 #include <unistd.h>
 2 #include <stdio.h>
 3 #include <stdlib.h>
 4 #include <fcntl.h>
 5 #include <termios.h>
 6
 7 main(int argc, char *argv[])
 8 {
 9     struct termios tty, savtty;
10     char ch, line[BUFSIZ];
11     FILE *fp;
12
13     if ((fp = fopen(argv[1], "r")) == NULL) {
14         printf("Cannot open %s\n", argv[1]);
15         exit(1);
16     }
17     tcgetattr(fileno(stdin), &tty);
18     savtty = tty;
19     tty.c_lflag &= ~(ISIG | ICANON | ECHO);
20     tty.c_cc[VMIN] = 0;     /* no characters */
21     tty.c_cc[VTIME] = 1;    /* wait for 100 msec */
22     tcsetattr(fileno(stdin), TCSANOW, &tty);
23
24     while (fgets(line, BUFSIZ, fp) != NULL) {
25         if (read(fileno(stdin), &ch, 1) == 1) {
26             tty.c_cc[VMIN] = 1;     /* one char */
27             tcsetattr(fileno(stdin), TCSANOW, &tty);
28             read(fileno(stdin), &ch, 1);
29             tty.c_cc[VMIN] = 0;     /* no chars */
30             tcsetattr(fileno(stdin), TCSANOW, &tty);
31         }
32         fputs(line, stdout);
33     }
34     tcsetattr(fileno(stdin), TCSANOW, &savtty);
35     fclose(fp);
36 }