Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

setvbuf not able to make stdin unbuffered

My main intention was to make getchar return as soon as it gets a character instead of waiting for the ENTER key. I tried this

int main()
{
    setvbuf(stdin,NULL,_IONBF,0);
    getchar();

    return 0;
}

Comparing this with the prototype of setvbuf

setvbuf ( FILE * stream, char * buffer, int mode, size_t size );

it should set stdin to unbuffered mode.

But still getchar() keeps waiting for ENTER

I've seen related posts like this

Printing while reading characters in C

which are suggesting alternate methods to make stdin unbuffered. But I am curious to know as to why setvbuf method does not work

like image 873
Pavan Manjunath Avatar asked Apr 20 '12 13:04

Pavan Manjunath


2 Answers

The terminal driver doesn't return anything until you hit return, even if the read() operation would accept what's already there.

To get character-by-character input from a terminal, you have to get it out of canonical mode into raw or cbreak mode, and that requires different operations altogether. Take a look at the POSIX manual on 'General Terminal Interface' for how to control the terminal. Or consider using the curses library.

See also: Canonical vs non-canonical terminal input

like image 138
Jonathan Leffler Avatar answered Sep 26 '22 01:09

Jonathan Leffler


In case you are trying this under Linux or another Unix-like system, it is the terminal that buffers the input and only passes an entire line. You can use ncurses to circumvent this:

#include <ncurses.h>

int main()
{
    initscr();
    getch();
    endwin();

    return 0;
}

Compile with:

gcc -o main main.c -lncurses
like image 41
user1202136 Avatar answered Sep 26 '22 01:09

user1202136