我在 C 项目中使用该库,在初始化和取消初始化curses 后ncurses遇到了使用printf()/的问题。这是一个简化的说明:puts()
initscr();
endwin();
puts("first");
usleep(1e6);
puts("second");
Run Code Online (Sandbox Code Playgroud)
first仅second当包含的可执行文件退出后(一秒多一点后), 和 才会出现在屏幕上,而不是先打印,first然后在一秒后打印second. ncurses似乎以stdout某种方式缓冲并且仅在退出时刷新它。fflush(stdout)似乎解决了问题:
initscr();
endwin();
puts("First.");
fflush(stdout);
usleep(1e6);
puts("Second");
Run Code Online (Sandbox Code Playgroud)
当stdout手动刷新时,输出将按预期显示(带有第二个间隙)。puts()不过,如果我之后要usleep()在中间添加更多语句,我需要在每个语句之后重复调用fflush(stdout),并且我想知道是否有更好的解决方案,例如将程序永久重置为预诅咒模式。
ncurses调用setvbuf,将流置于全缓冲模式。要么指定环境变量NCURSES_NO_SETBUF来指示它不更改缓冲,要么通过setvbuf再次调用来恢复缓冲模式,尽管man 3 setvbuf建议不要这样做:
setvbuf() 函数可以随时使用,但如果流处于“活动”状态,则可能会产生特殊的副作用(例如丢弃输入或刷新输出)。便携式应用程序应该在任何给定的流上仅在执行任何 I/O 之前调用它一次。
以下是如何恢复stdout行缓冲和stderr再次无缓冲:
#include <stdio.h>
#include <unistd.h>
#include <ncurses.h>
int main() {
initscr();
endwin();
setvbuf(stdout, NULL, _IOLBF, 0);
setvbuf(stderr, NULL, _IONBF, 0);
puts("First.");
usleep(1e6);
puts("Second");
return 0;
}
Run Code Online (Sandbox Code Playgroud)