Основы программирования в Linux - Страница 93
Изменить размер шрифта:
}Сохраните эту программу как menu5.с.
Как это работает
Переписанная функция
getchoiceterminfomainsleepdo { choice = getchoice("Please select an action", menu, input, output); printf("nYou have chosen: %cn", choice); sleep(1);} while (choice != 'q');Последняя функция в этой программе
char_to_terminalputcВ завершение этой главы бегло рассмотрим пример определения нажатий клавиш.
Обнаружение нажатий клавиш
Пользователи, программировавшие в ОС MS-DOS, часто ищут в ОС Linux эквивалент функции
kbhitkbhitОднако, когда вы переносите программы из MS-DOS, часто удобно эмулировать функцию
kbhitУпражнение 5.7. Исключительно ваша собственная
kbhit1. Начните со стандартной заголовочной информации и пары структур для установки параметров терминала.
peek_character#include <stdio.h>#include <stdlib.h>#include <termios.h>#include <term.h>#include <curses.h>#include <unistd.h>static struct termios initial_settings, new_settings;static int peek_character = -1;void init_keyboard();void close_keyboard();int kbhit();int readch();2. Функция main вызывает функцию
init_keyboardkbhit, функциявосстанавливает нормальный режим и программа завершается:close_keyboardint main() {int ch = 0;init_keyboard();while (ch != 'q') {printf("loopingn");sleep(1);if (kbhit()) {ch = readch();printf("you hit %cn", ch);}}close_keyboard();exit(0);}3. Функции
иinit_keyboardнастраивают терминал в начале и конце программы:close_keyboardvoid init_keyboard() {tcgetattr(0, &initial_settings);new_settings = initial_settings;new_settings.c_lflag &= ~ICANON;new_settings.c_lflag &= ~ECHO;new_settings.c_lflag &= ~ISIG;new_settings.c_cc[VMIN] = 1;new_settings.c_cc[VTIME] = 0;tcsetattr(0, TCSANOW, &new_settings);}void close_keyboard() {tcsetattr(0, TCSANOW, &initial_settings);}4. Теперь функция, проверяющая нажатие клавиши:
int kbhit() {char ch;int nread;if (peek_character != -1) return 1;new_settings.c_cc[VMIN] = 0;tcsetattr(0, TCSANOW, &new_settings);nread = read(0, sch, 1);newrsettings.c_cc[VMIN] = 1;tcsetattr(0, TCSANOW, &new_settings);if (nread == 1) {peek_character = ch;return 1;}return 0;}5. Нажатый символ считывается следующей функцией
, которая затем восстанавливает значение -1 переменнойreadchдля выполнения следующего цикла:peek_characterint readch() {char ch;if (peek_character != -1) {ch = peek_character;peek_character = -1;return ch;}read(0, &ch, 1);