I'm using the ncurses
library in a C project, and encountered a problem with the use of printf()
/puts()
after curses was initialized and de-initialized. Here's a simplified illustration:
initscr();
endwin();
puts("first");
usleep(1e6);
puts("second");
Both first
and second
will appear on the screen only after the containing executable exits (after a little over one second), instead of printing first
first, and then, a second later, second
. ncurses
seems to be buffering stdout
somehow and only flushing it on exit. fflush(stdout)
seems to solve the problem:
initscr();
endwin();
puts("First.");
fflush(stdout);
usleep(1e6);
puts("Second");
When stdout
is manually flushed, output is displayed as expected (with a second gap). If I were to add more puts()
statements afterwards with usleep()
s in between, though, I'd need to repeat the calls to fflush(stdout)
after each one, and I'm wondering if there's a better solution that, say, permanently resets the program to pre-curses mode.
ncurses
calls setvbuf
, putting streams to a full buffered mode. Either specify the environment variable NCURSES_NO_SETBUF
to instruct it to not change buffering, or restore the buffer mode by calling setvbuf
again, although man 3 setvbuf
advises against this:
The setvbuf() function may be used at any time, but may have peculiar side effects (such as discarding input or flushing output) if the stream is ``active''. Portable applications should call it only once on any given stream, and before any I/O is performed.
Here is how to restore stdout
to line-buffering and stderr
to no buffering again:
#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;
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With