为什么在这种情况下会显示 printw?

Why printw does display in this case?

为什么在这种情况下,printw 显示 "Blah"?我使用 nocbreak。所以 printw 不应该正常产生输出,因为输出是行缓冲的。

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

是因为调用了refresh

refresh man page 没有明确说明,但它似乎也适用于缓冲输出。

如果不调用 refresh,则不会显示任何输出。

如果您添加对 getch 而不是 refresh 的调用,您也会得到输出,因为 getch 执行 wrefreshMan page:

If the window is not a pad, and it has been moved or modified since the last call to wrefresh, wrefresh will be called before another character is read.

要查看 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模式下,只有在你按下return后才会接收并输出。

实际上,printw而不是line-buffered。 ncurses 将终端初始化为raw 模式 并根据需要模拟cooked 模式。但这仅适用于 input。对于输出,ncurses 会立即将相关更新写入屏幕,如 manual page:

中所述

The refresh and wrefresh routines (or wnoutrefresh and doupdate) must be called to get actual output to the terminal, as other routines merely manipulate data structures. The routine wrefresh copies the named window to the physical screen, taking into account what is already there to do optimizations. The refresh routine is the same, using stdscr as the default window. Unless leaveok has been enabled, the physical cursor of the terminal is left at the location of the cursor for that window.

物理屏幕当然是您的终端。 ncurses 通过在 curscr:

中记录它来记住那里的内容

This implementation of curses uses a special window curscr to record its updates to the terminal screen.

This is referred to as the "physical screen" in the curs_refresh(3x) and curs_outopts(3x) manual pages.

从 ncurses 的角度来看,终端(您 看到)和 curscr 是一回事。

对于printw, the manual page says it acts as if it calls waddstr,然后依次调用waddch:

These functions write the (null-terminated) character string str on the given window. It is similar to calling waddch once for each character in the string.