Hello world!

Вітаємо у світі curses. Перед тим як поринути в бібліотеку і розглянути її різноманітні можливості, давайте напишемо простеньку програму - традиційну "Hello World".

Компіляція з бібліотекою NCURSES

Щоб користуватися функціями бібліотеки, ви повинні включити ncurses.h у вашу програму. Для того, щоб прив'язати програму до ncurses, потрібно також додати прапорець -lncurses під час компіляції.

#include <ncurses.h>
.
. (текст програми)
.

компіляція і прив'язка:

gcc <файл програми> -lncurses

Приклад 1. Програма Hello World !!!

#include <ncurses.h>

int main()
{
    initscr();                  /* розпочинає режим curses        */
    printw("Hello World !!!");  /* друкує Hello World             */
    refresh();                  /* виводить його на дійсний екран */
    getch();                    /* очікує користувацького вводу   */
    endwin();                   /* завершує режим curses          */

    return 0;
}

Аналіз

Вищенаведена програма виводить на екран "Hello World !!!" і завершує роботу. Вона демонструє як започаткувати curses, здійснити певні маніпуляції на екрані, та завершити режим curses. Давайте розглянемо її рядок за рядком.

initscr()

Функція initscr() встановлює режим curses для терміналу. В деяких втіленнях, вона очищає екран і виводить порожній. Для того, щоб можна було здійснити якісь дії за допомогою функцій curses, спершу необхідно викликати initscr(). Вона ініціює систему curses, виділяє пам'ять для нашого поточного вікна (під назвою stdscr) і ще деяких структур даних. За виняткових обставин, ця функція може зазнати невдачі внаслідок недостатнього обсягу пам'яті для структур даних бібліотеки curses.

Після виклику initscr(), ми можемо приступити до різноманітних ініціалізацій для налагодження параметрів curses.

Загадкова refresh()

Наступний рядок із printw друкує "Hello World !!!". Ця функція аналогічна до звичної printf(3) в усіх відношеннях, за винятком того, що вона друкує дані у вікно із назвою stdscr, розташовуючи текст згідно з поточними координатами (y, x). Оскільки нашими поточними координатами являються (0, 0), ланцюжок буде виведено в лівому верхньому куті вікна.

Тепер ми добралися до нашої загадкової refresh(). Коли ми викликали printw, дані було, насправді, записано до уявного вікна, яке не відображається на дійсному екрані. Робота printw полягає в оновленні декількох прапорців і структур даних, і запису даних до буферу, що відповідає stdscr. Для того, щоб дійсно вивести їх на екрані, нам необхідно викликати refresh(), яка вкаже системі curses скинути вміст буферу на екран.

Ідея, що криється за всім цим, полягає у наданні програмісту можливості багатократної зміни уявного екрану або вікон із послідуючим викликом лише одного refresh() для відображення змін на екрані. refresh() перевіряє вікно і оновлює під час виводу тільки ті частини, які було змінено. Це покращує ефективність, одночасно надаючи додаткову гнучкість. Але часом, це дратує початківців. Звична помилка початківців - це забути викликати refresh() після певних оновлень за допомогою класу функцій printw(). Іноді, навіть я забуваю викликати її... :-)

endwin()

І нарешті, не забудьте завершити режим curses. У протилежному випадку, ваш термінал може поводитися дивно по закінченню програми. endwin() звільняє пам'ять, зайняту підсистемою curses та її структурами даних, і встановлює термінал у звичайний режим.