【问题标题】:setvbuf not able to make stdin unbufferedsetvbuf 无法使标准输入无缓冲
【发布时间】:2012-05-02 02:52:02
【问题描述】:

我的主要目的是让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

我看过类似的相关帖子

Printing while reading characters in C

建议使用其他方法使stdin 无缓冲。但我很想知道为什么setvbuf 方法不起作用

【问题讨论】:

  • 您必须在流上的任何“移动”之前调用setvbuf()...所以第一件事是main()
  • @pmg 我更新了我的帖子以反映我的尝试。但是还是不行
  • 我认为问题不在于setvbuf()。我尝试了使用和不使用 setvbuf() 的程序,但行为不同。如果没有setvbuf(),所有直到并包括 ENTER 的字符都会被消耗(即使它仅在输入 ENTER 后才会被消耗); setvbuf() 仅消耗第一个字符,其余字符用作以下 bash 命令。

标签: c buffer stdin getchar unbuffered


【解决方案1】:

在您点击返回之前,终端驱动程序不会返回任何内容,即使 read() 操作会接受已经存在的内容。

要从终端获取逐个字符的输入,您必须将其从规范模式转换为原始模式或 cbreak 模式,这需要完全不同的操作。查看'General Terminal Interface' 上的 POSIX 手册,了解如何控制终端。或者考虑使用curses 库。

另见:Canonical vs non-canonical terminal input

【讨论】:

  • setvbuf(stdin,NULL,_IONBF,0); 应该这样做对吗?我的意思是setvbuf 适用于所有文件指针,但不适用于stdin
  • 没有。 setvbuf() 只是告诉程序中的标准 I/O 库不要使用缓冲区;它不会告诉终端驱动程序任何事情。
【解决方案2】:

如果您在 Linux 或其他类 Unix 系统下尝试此操作,终端会缓冲输入并仅传递整行。您可以使用 ncurses 来规避这一点:

#include <ncurses.h>

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

    return 0;
}

编译:

gcc -o main main.c -lncurses

【讨论】:

  • 感谢您的回复。我看到了这些替代方法,但我很好奇为什么 setvbuf 不起作用
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2011-05-03
  • 1970-01-01
  • 2020-08-04
  • 1970-01-01
  • 2014-12-07
  • 2011-05-18
  • 1970-01-01
相关资源
最近更新 更多