Почему printw отображается в этом случае? - PullRequest
0 голосов
/ 21 мая 2019

Почему в этом случае printw отображает «Бла»?Я использую nocbreak.Так что printw не должен выводить нормально, потому что вывод буферизирован.

int main(int ac, char **av)
{
    initscr();
    nocbreak();
    printw("Blah");
    refresh();
    while (1);
}

Ответы [ 2 ]

3 голосов
/ 22 мая 2019

На самом деле printw - это , а не с линейной буферизацией. ncurses инициализирует терминал на сырой режим и имитирует приготовленный режим при необходимости. Но это относится только к input . Для вывода ncurses немедленно запишет соответствующие обновления на экран, как указано на странице руководства :

Процедуры refresh и wrefresh (или wnoutrefresh и doupdate) должны вызываться для получения фактического вывода на терминал, так как другие процедуры просто манипулируют структурами данных. Подпрограмма wrefresh копирует названный окно на физический экран , с учетом того, что уже там делать оптимизации. Процедура refresh такая же, с использованием stdscr в качестве окна по умолчанию. Если leaveok не включено, физический курсор терминала остается на месте курсора для это окно.

Физический экран - это, конечно, ваш терминал. ncurses запоминает, что там, записывая это в curscr:

Эта реализация curses использует специальное окно curscr для записи его обновления на экране терминала.

Это называется "физическим экраном" в curs_refresh (3x) и curs_outopts (3x) справочные страницы.

С точки зрения ncurses, терминал (который вы видите ) и curscr - это одно и то же.

Для printw, на странице руководства сказано, что она действует так, как будто она вызывает waddstr, и это в свою очередь звонки waddch:

Эти функции записывают (оканчивающуюся нулем) строку символов str на данное окно. Это похоже на вызов waddch один раз для каждого символа в строке.

1 голос
/ 21 мая 2019

Это из-за звонка на refresh.

Обновленная справочная страница не указывает это явно, но, похоже, также применяет буферизованные выходные данные.

Без вызова refresh вывод не отображается.

Если вы добавите вызов к getch вместо refresh, вы получите также вывод, потому что getch делает wrefresh. Справочная страница :

Если окно не является пэдом, и оно было перемещено или изменено с момента последнего вызова wrefresh, то wrefresh будет вызываться до прочтения другого символа.

Чтобы увидеть различное поведение входов в режиме cbreak / nocbreak, вы можете использовать эту программу:

int main(int ac, char **av)
{
    char c, i;
    initscr();
    noecho();  // switch off display of typed characters by the tty

    printw("cbreak\n");
    cbreak();
    for (i = 0; i < 5; ++i) {
        c = getch();
        printw("%c", c);
    }

    printw("\nnocbreak\n");
    nocbreak();
    for (i = 0; i < 5; ++i) {
        c = getch();
        printw("%c", c);
    }

    return 0;
}

В режиме cbreak программа видит пять вводимых символов по мере их ввода (и выводит сразу из-за getch). В режиме nocbreak они будут приниматься и выводиться только после нажатия клавиши возврата.

...