清除C中的输入缓冲区

时间:2014-07-31 09:55:23

标签: c buffer

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

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

此代码有效并等待我按回车键退出循环。问题是,循环等待我按Enter键,任何其他键将在屏幕上输出(不可读)。我的问题是,有没有其他方法来清除输入缓冲区而不按任何东西,比如使用fflush来清除输出缓冲区?

1 个答案:

答案 0 :(得分:1)

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

您需要清楚两件事:

  1. C库管理的FILE *输入缓冲区。
  2. 程序尚未读取的OS输入缓冲区。
  3. 第一个可以用fflush清除,就像输出流一样,只是数据被丢弃而不是写出来。

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

    首先,您需要使用select来查看read操作是否会阻止。这有效地检查OS缓冲区是否清除。如果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
    }
    

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