为什么在这种情况下会显示 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
执行 wrefresh
。 Man 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.
为什么在这种情况下,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
执行 wrefresh
。 Man 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
andwrefresh
routines (orwnoutrefresh
and doupdate) must be called to get actual output to the terminal, as other routines merely manipulate data structures. The routinewrefresh
copies the named window to the physical screen, taking into account what is already there to do optimizations. Therefresh
routine is the same, usingstdscr
as the default window. Unlessleaveok
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.