Основы программирования в Linux
Режимы клавиатуры
Процедуры считывания с клавиатуры управляются режимами. Режимы устанавливаются с помощью следующих функций:
<b>#include <curses.h></b><b>int echo(void);</b><b>int noecho(void);</b><b>int cbreak(void);</b><b>int nocbreak(void);</b><b>int raw(void);</b><b>int noraw(void);</b>Функции
иechoпросто включают и отключают отображение символов, набираемых на клавиатуре. Оставшиеся четыре функции управляют тем, как символы, набранные на терминале, становятся доступны программе с применением curses. Для того чтобы понять функциюnoecho, необходимо иметь представление о стандартном режиме ввода. Когда программа, использующая библиотеку curses, стартует с вызова функцииcbreak, устанавливается режим ввода, называемый режимом с обработкой (cooked mode). Это означает построчную обработку, т.е. ввод становится доступен программе после нажатия пользователем клавиши <Enter> (или <Return> на некоторых клавиатурах). Специальные символы на клавиатуре включены, поэтому набор соответствующих клавиатурных последовательностей может сгенерировать сигнал в программе. Управление потоком, если терминал запускается с терминала, также включено. Вызывая функциюinitscr, программа может установить режим вводаcbreak, в котором символы становятся доступными программе сразу после их набора, а не помещаются в буфер и передаются программе только после нажатия клавиши <Enter>. Как и в режиме с обработкой, специальные символы клавиатуры действуют, а простые клавиши, например <Backspace>, передаются для обработки непосредственно в программу, поэтому если вы хотите, чтобы нажатие клавиши <Backspace> приводило к привычным действиям, то вы должны запрограммировать их самостоятельно.cbreakВызов функции
отключает обработку специальных символов, поэтому становится невозможной генерация сигналов или управление потоком с помощью набранных на клавиатуре специальных символьных последовательностей. Вызов функцииrawвозвращает режим ввода в режим с обработкой символов, но режим обработки специальных символов не изменяет; вызовnocbreakвосстанавливает и режим с обработкой, и обработку специальных символов.norawКлавиатурный ввод
Чтение с клавиатуры — очень простая операция. К основным функциям чтения относятся следующие:
<b>#include <curses.h></b><b>int getch(void);</b><b>int getstr(char *string);</b><b>int getnstr(char *string, int number_of_characters);</b><b>int scanw(char *format, ...);</b>Все они действуют подобно своим аналогам, не входящим в библиотеку curses,
,getcharиgets. Обратите внимание на то, что у функцииscanfнет возможности ограничить длину возвращаемой строки, поэтому применять ее следует с большой осторожностью. Если ваша версия библиотеки curses поддерживает функциюgetstr, позволяющую ограничить количество считываемых символов, всегда применяйте ее вместо функцииgetnstr. Это очень напоминает поведение функцийgetstrиgets, с которыми вы познакомились в главе 3.fgetsВ упражнении 6.3 для демонстрации управления клавиатурой приведен пример короткой программы ipmode.c.
Упражнение 6.3. Режим клавиатуры и ввод1. Наберите программу и включите в нее начальные вызовы библиотеки curses:
#include <unistd.h>#include <stdlib.h>#include <curses.h>#include <string.h>#define PW_LEN 256#define NAME_LEN 256int main() {char name[NAME_LEN];char password[PW_LEN];const char *real_password = "xyzzy";int i = 0;initscr();move(5, 10);printw("%s", "Please login:");move(7, 10);printw("%s", "User name: ");getstr(name);move(9, 10);printw("%s", "Password: ");refresh();2. Когда пользователь вводит свой пароль, необходимо остановить отображение символов на экране. Далее сравните введенный пароль со строкой xyzzy:
cbreak();noecho();memset(password, '\0', sizeof(password));while (i < PW_LEN) {password[i] = getch();if (password[i] == '\n') break;move(8, 20 + i);addch('*');refresh();i++;}3. В заключение восстановите отображение символов и выведите сообщение об успешном или неудачном завершении:
echo();nocbreak();move(11, 10);if (strncmp(real_password, password, strlen(real_password)) == 0)printw("%s", "Correct");else printw("%s", "Wrong");printw("%s", " password");refresh();