setvbuf не в состоянии сделать stdin unbuffered


Моим главным намерением было заставить getchar возвратиться, как только он получит символ, а не ждать ключаENTER . Я попробовал это

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

    return 0;
}

Сравнивая это с прототипом setvbuf

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

Он должен установить stdin в режим без буфера.

Но все равно getchar() продолжает ждать ENTER

Я видел похожие сообщения, как это

Печать при чтении символов в C

Которые предлагают альтернативные методы, чтобы сделать stdin без буфера. Но мне любопытно узнать, почему метод setvbuf не работает

2 10

2 ответа:

Драйвер терминала ничего не возвращает, пока вы не нажмете кнопку return, даже если операция read() примет то, что уже есть.

Чтобы получить символьный ввод от терминала, вы должны вывести его из канонического режима в режим raw или cbreak, а это требует совершенно разных операций. Взгляните на руководство POSIX по "общий интерфейс терминала" , чтобы узнать, как управлять терминалом. Или рассмотрите возможность использования библиотеки curses.

См. также: канонический vs неканонический терминальный вход

В случае, если вы пытаетесь сделать это под Linux или другой Unix-подобной системой, это терминал, который буферизует входные данные и передает только целую строку. Вы можете использовать ncurses, чтобы обойти это:

#include <ncurses.h>

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

    return 0;
}

Компиляция с помощью:

gcc -o main main.c -lncurses