我有一个大型程序,一个带有图形的文本扭曲游戏。在我的代码中的某处,我使用 kbhit()
我执行此代码来清除我的输入缓冲区:
while ((c = getchar()) != '\n' && c != EOF);
这段代码可以工作并等待我按回车键退出循环。问题是,循环等待我按 Enter,任何其他键都会在屏幕上输出(不可读)。我的问题是,有没有其他方法可以在不按任何东西的情况下清除输入缓冲区,例如使用 fflush 清除输出缓冲区?
最佳答案
假设您使用的是某种 Unix 变体......
这里您需要澄清两件事:
- 由 C 库管理的
FILE *
输入缓冲区。 - 您的程序尚未读取的操作系统输入缓冲区。
第一个可以用 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/