Глозштейну Александру Моисеевичу за то, что показал библиотеку ncurses.
Victor Wagner за то, что показал библиотеку PDCurses.
Отдельное спасибо E.L.K. за пример использования UTF-8 в ncurses.
И конечно всем тем, кто не мешал :).
Данный материал может копироваться без каких-либо ограничений абсолютно бесплатно.
Публикация либо включении данного документа в какой-либо пакет, дистрибутив и т.п.
возможна только с согласия автора.
Данное руководство многократно изменялось, по тому не исключены ошибки. Обнаруженные недочеты, поправки и дополнения просьба присылать автору.
Для изучения данного материала предполагается наличие у читателя начальных знаний языка С.текст на синем фоне обозначает исходный текст программы
текст на чёрном фоне обозначает команду, которую нужно выполнить в командной строке
Библиотека ncurses (аналог библиотеки crt в Pascal) предназначена для управления вводом выводом на терминал. Она позволяет программисту не беспокоиться об аппаратных различиях терминалов и писать достаточно переносимый код. Файлы библиотеки находятся в папке /usr/include/curses/, дополнительную информацию и примеры можно найти в /usr/share/doc/ncurses-версия_библиотеки и в /usr/share/doc/ncurses-devel-версия_библиотеки.
Библиотека ncurses построена на основе библиотеки curses. Есть и другие библиотеки, построенные на базе curses. Материал представленный здесь построен на общих функциях библиотек ncurses и PDCurses для создания максимально переносимых приложений.
Экран - окно максимального для данного терминала размера.
Терминал - экран, на котором располагаются окна.
Курсор - играет очень важную роль, он указывает на то место, куда будет осуществлён вывод. Таким образом, для вывода текста в необходимую позицию на экране нужно передвинуть курсор и осуществить вывод.
chtype тип символов, с которыми работает
ncurses (он включает в себя код символа, цвет и дополнительные атрибуты)
bool логический тип (может быть ложным FALSE или истинным TRUE)
WINDOW структура, хранящая данные окна
SCREEN структура, хранящая данные терминала
TRUE логическая истина (1)
FALSE логическая ложь (0)
Большинство функций возвращает код ошибки.
ERR значение, возвращаемое при ошибке (-1)
OK значение, возвращаемое при отсутствии ошибки
Подробнее о том в каких случаях и что возвращает конкретная функция можно узнать в документации или в man.
/******************************************************* sample1.c - пример простой программы передвигающей курсор в определённую позицию экрана и печатающей текст ********************************************************/ #include <ncurses.h> //подключаем библиотеку ncurses main(int argc,char *argv[]) { // инициализация (должна быть выполнена // перед использованием ncurses) initscr(); // перемещение курсора в стандартном экране y=10 x=30 move(10,30); printw("Hello world !!!"); // вывод строки refresh(); // обновить getch(); // ждём нажатия символа endwin(); // завершение работы с ncurses }
Что нового Вы увидели в этом примере?
1) Чтобы Вы смогли воспользоваться любой библиотекой её нужно подключить.
Для библиотеки ncurses это делается добавлением "#include <ncurses.h>"
в начале программы.
2) Для того чтобы начать работу с библиотекой ncurses необходимо её
проинициализировать. Для этого нужно вызвать функцию initscr().
3) При завершении работы с библиотекой ncurses нужно вызвать
endwin().
4) printw и getch аналогичны printf и getchar из <stdio.h>
5) библиотека ncurses позволяет ускорить вывод на экран за счёт
того, что она использует запись не непосредственно на экран, а
в буфер в памяти и когда нужно отобразить все изменения
при помощи функции refresh() выводится только изменившаяся
часть экрана.
Таким образом, каждая программа, использующая ncurses, будет иметь следующую структуру:
... #include <ncurses.h> ... initscr(); работа с ncurses endwin(); ...
Рассмотрим компиляцию программы использующую ncurses. Чтобы откомпилировать пример приведённый в листинге 1 нужно выполнить команду:
gcc sample1.c -o sample1 -lncurses
Если Вы уже компилировали программы в gcc, то наверно заметили, что добавился новый параметр -lncurses.
Для ввода-вывода в С используются такие функции как putchar, printf, scanf, getch. Однако их нельзя использовать вместе с библиотекой ncurses. Для ввода-вывода на экран в программах использующих ncurses могут использоваться только функции объявленные в самой библиотеке ncurses.
Вывод символа
int addch(const chtype ch)
выводит символ ch в текущую позицию курсора и перемещает курсор
на один символ вправо или в начало следующей строки, если курсор
находится у правой границы экрана.
(аналогична функции putchar из <stdio.h>)
chtype
тип символов с которыми работает ncurses (он включает в себя код
символа, цвет и дополнительные атрибуты).
Вставка символа
int insch(chtype ch)
вставляет символ ch слева от курсора и все символы стоящие после
курсора перемещаются на одну позицию вправо.
Вывод строки с преобразованием по формату
int printw(const char *fmt,...)
пример:
... i=1; printw("Значение i=%d",i); ...выведет Значение i=1
Вывод строки типа chtype*
int addchnstr(const chtype *chstr, int n)
выводит первые n символов или всю строку символов chstr, если n=-1 в позицию, где расположен курсор.
Вывод строки типа char*
int addstr(const char *str)
выводит строку str в позицию, где расположен курсор.
Вставка строки
int insnstr(const char* str, int n)
вставляет первые n символов или всю строку символов str, если n=-1 в позицию, где расположен курсор.
(положение курсора не изменяется, то что стояло справа от курсора сдвигается вправо)
Вставка пустой строки
int insertln()
вставляет пустую строку (строки стоящие ниже начиная с текущей сдвигаются вниз на одну строку)
Для символов типа chtype можно устанавливать такие
атрибуты, как мигание или цвет символа и фона.
Для добавления символу атрибута мигания нужно включить флажок A_BLINK.
Далается это так:
chtype ch = 'w' | A_BLINK;
Теперь при выводе этого символа он будет мигать, если конечно это позволяет
сделать терминал.
(A_DIM - пониженная яркость, A_BOLD - повышенная яркость, A_NORMAL - нормальное отображение, A_UNDERLINE - подчёркнутый, A_REVERSE - инверсный)
С включением цвета немного сложнее. Перед использованием цветов нужно проинициализировать палитру. Палитра это структура, в которой определённой цифре соответствует определённый цвет. В нашем случае одной цифре соответствуют сразу два цвета символов и фона.
... chtype ch; ... if (!has_colors()) { endwin(); printf("Цвета не поддерживаются"); exit(1); } start_color(); // 1 цвет в палитре - красные символы на чёрном фоне init_pair(1, COLOR_RED, COLOR_BLACK); // 2 цвет в палитре - зелёные символы на желтом фоне init_pair(2, COLOR_GREEN, COLOR_YELLOW); ... ch = 'w' | COLOR_PAIR(1); // символ с цветом 1 из палитрыФункция has_colors позволяет узнать можно ли использовать цвета. Функция start_color() должна вызываться до задания палитры. Функция init_pair() нужна чтобы задать какой цифре какой цвет будет соответствовать от 1 до COLOR_PAIRS-1 (0 зарезервирован для стандартного отображения). Для использования цвета в символе нужно включить флажок COLOR_PAIR(номер из палитры).
Следующие функции позволяют установить атрибуты вывода по умолчанию:
Включение атрибутов
int attron(int attrs)
включает атрибуты attrs.
(Например attron(COLOR_PAIR(1)); устанавливает цвет 1 из палитры)
Отключение атрибутов
int attroff(int attrs)
отключает атрибуты attrs.
(Например attroff(A_BLINK); отключает мигание)
Установка атрибутов
int attrset(int attrs)
Заменяет текущие атрибуты атрибутами attrs
(Например attrset(A_NORMAL); заменяет текущие атрибуты на A_NORMAL)
Установка атрибутов очистки
void bkgdset(chtype ch)
Устанавливает атрибуты с которыми очищается экран такими функциями как clear().
(Например bkgdset(COLOR_PAIR(1)); очистка будет осуществляться цветом 1 из палитры)