Функції виводу

Я гадаю, вам вже кортить побачити трохи дії. Тож повернемося до нашої одисеї по функціям curses. Щойно ми ініціювали curses, давайте спробуємо взаємодію зі світом.

Існує три класи функцій, призначених для виводу на екран.

  1. клас addch(): Виводить по одному символу з атрибутами.
  2. клас printw(): Виводить форматований ланцюжок, подібно до printf().
  3. клас addstr(): Виводить ланцюжки.

Ці функції можна використовувати взаємозамінно, і це питання стилю, щодо того, який з цих класів вживати. Давайте розглянемо кожну з них уважніше.

Клас функцій addch()

Ці функції додають по одному символу у поточне положення курсору, та переміщують курсор у наступну позицію. Часто вони застосовуються, щоб вивести знак з певними атрибутами. Атрибути пояснено докладніше в подальших розділах цього документу.

Ви маєте дві можливості, щоб об'єднати символ з певним атрибутом:

  1. Шляхом операції логічного АБО між символом із бажаним макросом атрибуту. Ці макроси можна знайти в заголовковому файлі ncurses.h. Наприклад, якщо би вам хотілося вивести символ ch (типу char) жирним шрифтом і підкресленим, виклик addch() виглядав би як наступне

     addch(ch | A_BOLD | A_UNDERLINE);
    
  2. Шляхом використання функцій на кшталт attrset(), attron(), attroff(). Ці функції розглянуто в розділі "Атрибути". Якщо коротко, то вони керують поточними атрибутами вказаного вікна. Як тільки якийсь атрибут задано, всі надруковані знаки виводитимуться з цим атрибутом до тих пір, доки його не буде скасовано.

Додатково, curses надає деякі спеціальні знаки для символьної графіки. Ви в-змозі зображати таблиці, горизонтальні та вертикальні лінії тощо. Всі доступні знаки можна знайти в заголовковому файлі ncurses.h, у макросах, що розпочинаються з ACS_.

mvaddch(), waddch() і mvwaddch()

mvaddch() використовується, щоб перемістити курсор у вказаний пункт, а потім надрукувати. Таким чином, виклики

move(row,col); /* перемішує курсор у рядок row і стовпчик col */
addch(ch);     /* друкує */

можна поміняти на один

mvaddch(row,col,ch);

waddch() аналогічна addch() за винятком того, що вона додає знак у вказане вікно. (Пам'ятаймо, що addch() записує до stdscr.)

Схожим чином, функція mvwaddch() використовується для додання символу у вказане вікно і вказані координати.

Ми ознайомились із базовою функцією виводу addch(). Але якщо нам хотілося би вивести ланцюжок, було би досить нудно виводити його символ за символом. На щастя, ncurses передбачає функції, подібні до стандартних printf(3) та ?puts(3).

Клас функцій printw()

Ці функції схожі до printf(3) із доданою можливістю друкувати в будь-якому місці екрану.

printw() і mvprintw()

Ці дві функції працюють подібно до printf(3). mvprintw() можна використати для переміщення курсору до вказаної позиції і подальшим друком. Якщо би ви хотіли спочатку перемістити курсор, а потім друкувати за допомогою printw(), скористайтеся з попереднього move(), а потім printw(), хоч я не бачу змісту в униканні mvprintw().

wprintw() і mvwprintw()

Ці дві функції аналогічні попереднім двом, за винятком того, що вони друкують у відповідне вікно, надане як аргумент.

vwprintw()

Ця функція схожа до стандартної vprintf(3). Використовується для друку змінної кількості аргументів.

Простий приклад printw()

Приклад 3. Використання printw()

#include <ncurses.h>                /* ncurses.h включає stdio.h */
#include <string.h>

int main()
{
    char mesg[] = "Just a string";  /* Повідомлення, яке з'явиться на екрані */
    int row, col;                   /* Змінні, в яких зберігатиметься *
                                     * кількість рядків і стовпчиків екрану */
    initscr();                      /* Розпочинає режим curses */
    getmaxyx(stdscr, row, col);     /* Отримає кількість рядків і стовпчиків *
                                     * екрану */
    mvprintw(row / 2, (col - strlen(mesg)) / 2, "%s", mesg);
    /* Виведе повідомлення у центрі екрану   */
    mvprintw(row - 2, 0, "This screen has %d rows and %d columns\n", row,
         col);
    printw
    ("Try resizing your window (if possible) and then run this program 
             again");
    refresh();
    getch();
    endwin();

    return 0;
}

Вищенаведена програма демонструє, наскільки легко користуватися printw. Ви тільки вказуєте координати і текст повідомлення, і функція здійснює те, що ви їй вказали.

В цій програмі також з'явилась нова функція getmaxyx() - макрос, визначений у ncurses.h. Вона повертає кількість рядків і стовпчиків вказаного вікна (у нашому випадку - stdscr). Оскільки getmaxyx() втілено як макрос, не дозволяється передати їй покажчики як аргументи, ми просто вказуємо дві змінні типу int, перша - y, а друга - x.

Клас функцій addstr()

addstr() використовується, щоб додати символьний ланцюжок у вказане вікно. Ця функція тотожна виклику addch() для кожного символу наданого ланцюжка. Це справджується для всіх функцій виводу. Існують ще й інші функції з цього сімейства, такі як mvaddstr(), mvwaddstr() і waddstr(), що підпорядковуються умовності надання назв функціям curses (тобто mvaddstr() тотожна відповідному викликові move(), а потім addstr()). Іншою функцією з цього сімейства є addnstr(), яка візьме також параметр-ціле (скажімо n). Ця функція додасть щонайбільше n знаків до екрану. Якщо n від'ємне, тоді увесь ланцюжок буде додано.

Невеличке попередження

Всі ці функції беруть, як аргументи, першою координатою y, а потім x. Поширеною помилкою новачків є вказування координат як (x, y), замість (y, x). Ось схематичне зображення системи координат екрану:

(0, 0)                  x 
   *---1---2---3---4---5-->
   |           :
   1           :
   |           :
   2...........:
   |            (2, 3)
   3           
y  |           
   V

Окрім абсолютної системи координат stdscr-екрану, використовується також відносна система всередині вікон. Всередині вікон, правий верхній кут вікна матиме знову ж таки координату (0, 0). Типово, функції, чия назва починається з 'w' використовують систему координат вікна.