清除 C 中的输入缓冲区

标签 c buffer

我有一个大型程序,一个带有图形的文本扭曲游戏。在我的代码中的某处,我使用 kbhit() 我执行此代码来清除我的输入缓冲区:

while ((c = getchar()) != '\n' && c != EOF);    

这段代码可以工作并等待我按回车键退出循环。问题是,循环等待我按 Enter,任何其他键都会在屏幕上输出(不可读)。我的问题是,有没有其他方法可以在不按任何东西的情况下清除输入缓冲区,例如使用 fflush 清除输出缓冲区?

最佳答案

假设您使用的是某种 Unix 变体......

这里您需要澄清两件事:

  1. 由 C 库管理的 FILE * 输入缓冲区。
  2. 您的程序尚未读取的操作系统输入缓冲区。

第一个可以用 fflush 清除,就像输出流一样,只不过数据只是被丢弃而不是写出。

第二个需要一些低级操作系统 I/O 调用。一般来说,您不应将它们与 FILE * I/O 函数混合使用,但它们在 fflush 和任何其他读取/获取操作之间应该是安全的。

首先,您需要使用 select 来查看 read 操作是否被阻止。这可以有效地检查操作系统缓冲区是否已清除。如果read不会阻塞,那么您执行单字符read,然后重复选择。关键是在读取之前必须检查是否有数据要读取并丢弃,否则会阻塞直到有数据读取。

代码可能看起来像这样(未经测试):

fflush(stdin);
int stdinin_fd = fileno(stdin);

while (1) {
    fdset readset;
    FD_ZERO(&readset);
    FD_SET(stdin_fd, &readset);
    struct timeval timeout = {0, 0};

    int result = select(stdin_fd+1, &readset, NULL, NULL, timeout);
    if (result == 1) {
        char c;
        read(stdin_fd, &c, 1);
    } else if (result == 0
               || (result == -1 && errno != EINTR)) {
        break;
    } // else loop
}

在清除操作系统缓冲区时可能会使用更大的读取大小,这会更有效,但我不确定它的可移植性,无论如何我假设不会有太多数据清除。

关于清除 C 中的输入缓冲区,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25055920/

相关文章:

Golang - 如何克服 bufio 的 Scan() 缓冲区限制?

c - 意外输入 62;9;c62;9;c62;9;c62;9;c 在将缓冲区写入标准输出后出现在 shell 中

python - 如何解决按顺序将文件附加到另一个文件时的内存问题

C 结构数组元素初始化转换

c++ - FSCANF 阅读撇号和连字符时遇到问题?

c - 在 C 预处理器中为其自身定义一些内容

c - 二维数组和指针 - C

c - fscanf 上大小 4 的读取无效

linux - 从汇编文件中读取

audio - 从 Nodejs 提供二进制/缓冲区/base64 数据