flushkey 函数并不是标准C库(ANSI C/C99/C11等)的一部分,它是一个非标准、平台特定的函数,主要用于某些特定的DOS环境。

在Windows、Linux或macOS等现代操作系统上,你无法直接使用 #include <some_header.h> 然后调用 flushkey()。
下面我将从几个方面为你详细解释这个函数:
flushkey 的作用和来源
flushkey 主要来源于 Turbo C 和 Borland C++ 这两个经典的DOS编译器,它的作用非常明确:
清空键盘缓冲区。

键盘缓冲区是一个内存区域,用于存储用户按下的键,即使你的程序还没有准备好读取它们。flushkey() 会强制清空这个缓冲区,丢弃其中所有尚未被程序处理的按键。
典型使用场景:
当你的程序需要等待用户输入一个特定的、不受干扰的字符时,为了避免用户之前不小心按下的键影响程序的判断,你可以在提示用户输入之前调用 flushkey()。
在DOS环境下的使用(Turbo C/Borland C++)
如果你正在使用一个古老的DOS环境(比如通过DOSBox运行Turbo C),你可以这样使用它:
#include <stdio.h>
#include <conio.h> // 包含 flushkey 函数的头文件
int main() {
printf("程序即将开始,请准备好按任意键...");
getch(); // 等待用户按下一个键(不显示)
printf("\n已清除之前的所有按键,现在请按 'Y' 或 'N' 来确认,\n");
// 在等待用户确认前,清空键盘缓冲区
// 这样即使用户之前按了Y或N,也不会被误读
flushkey();
char choice;
choice = getch();
if (choice == 'y' || choice == 'Y') {
printf("\n你选择了 Yes,\n");
} else if (choice == 'n' || choice == 'N') {
printf("\n你选择了 No,\n");
} else {
printf("\n无效的输入,\n");
}
return 0;
}
代码解释:

#include <conio.h>:这个头文件是Turbo C/Borland C++特有的,包含了像getch()(从键盘获取一个字符,不回显)和flushkey()这样的控制台输入/输出函数。flushkey():在提示用户输入 'Y' 或 'N' 之前调用,确保缓冲区是干净的,防止历史输入干扰本次操作。
在现代操作系统(Windows, Linux, macOS)上的替代方案
由于 flushkey() 不可用,我们需要使用现代操作系统提供的方法来实现相同的功能,核心思想都是清空输入缓冲区。
A. 在 Windows 平台
在Windows控制台程序中,你可以使用 <conio.h>(通常是编译器自带的,如MinGW)中的 kbhit() 和 getch() 组合来模拟,或者更彻底地使用 <windows.h> 中的函数。
使用 kbhit() 和 getch() 循环清空(推荐)
这是最常见、最简单的方法,不依赖于特定的Windows API,可移植性较好(只要你的编译器支持 conio.h)。
#include <stdio.h>
#include <conio.h> // Windows下(如MinGW)通常支持这个头文件
void clear_input_buffer() {
// 当键盘缓冲区中有字符时
while (kbhit()) {
// 读取并丢弃该字符
getch();
}
}
int main() {
printf("请按一些键,然后按回车继续...");
getchar(); // 等待用户按回车,期间用户可能按了很多其他键
printf("\n正在清空键盘缓冲区...\n");
clear_input_buffer();
printf("现在请按 'A' 键:");
char c = getch();
printf("\n你按下了: %c\n", c);
return 0;
}
使用Windows API(更底层)
如果你想直接调用Windows系统功能,可以使用 <windows.h>。
#include <stdio.h>
#include <windows.h> // Windows API头文件
void flush_windows_console_input() {
HANDLE hStdin = GetStdHandle(STD_INPUT_HANDLE);
DWORD numEvents;
INPUT_RECORD inputRecord;
// 获取输入缓冲区中的事件数量
GetNumberOfConsoleInputEvents(hStdin, &numEvents);
// 如果有事件,则将它们全部从缓冲区中移除(读取并丢弃)
if (numEvents > 0) {
// ReadConsoleInput 会消耗掉缓冲区中的事件
// 我们只需要循环读取直到没有事件为止
while (numEvents--) {
ReadConsoleInput(hStdin, &inputRecord, 1, &numEvents);
}
}
}
int main() {
printf("请按一些键,然后按回车继续...");
getchar(); // 等待回车
printf("\n正在清空键盘缓冲区...\n");
flush_windows_console_input();
printf("现在请按 'B' 键:");
// 使用 _getch() 或 _kbhit() 需要 <conio.h>
// 这里用另一种方式等待
system("pause > nul"); // 一个笨办法,但能演示
// 更好的方法是循环等待特定按键,这里省略
return 0;
}
B. 在 Linux 和 macOS 平台
在类Unix系统中,标准C库没有直接清空键盘缓冲区的函数,因为输入通常是行缓冲的(按回车才提交),但如果你想实现类似功能,可以读取标准输入直到缓冲区为空。
最常用的方法是使用 select() 系统调用来检查输入是否可读,然后使用 read() 来读取并丢弃。
#include <stdio.h>
#include <unistd.h>
#include <termios.h>
#include <sys/select.h>
// 设置终端为原始模式,以便逐个字符读取
void set_terminal_mode_raw() {
struct termios term;
tcgetattr(STDIN_FILENO, &term);
term.c_lflag &= ~(ICANON | ECHO); // 关闭规范模式和回显
tcsetattr(STDIN_FILENO, TCSANOW, &term);
}
// 恢复终端为标准模式
void set_terminal_mode_standard() {
struct termios term;
tcgetattr(STDIN_FILENO, &term);
term.c_lflag |= (ICANON | ECHO); // 开启规范模式和回显
tcsetattr(STDIN_FILENO, TCSANOW, &term);
}
// 清空标准输入缓冲区
void clear_stdin_buffer() {
fd_set fds;
struct timeval tv = {0, 0}; // 立即返回,不等待
FD_ZERO(&fds);
FD_SET(STDIN_FILENO, &fds);
// 检查是否有数据可读
if (select(STDIN_FILENO + 1, &fds, NULL, NULL, &tv) > 0) {
// 有数据,则读取并丢弃
char ch;
while (read(STDIN_FILENO, &ch, 1) > 0) {
// 不断读取直到缓冲区为空
}
}
}
int main() {
set_terminal_mode_raw();
printf("请按一些键,然后按 'q' 退出...\n");
char c;
while (1) {
read(STDIN_FILENO, &c, 1);
if (c == 'q') {
break;
}
}
printf("\n正在清空键盘缓冲区...\n");
clear_stdin_buffer();
printf("现在请按 'r' 键:");
while (1) {
read(STDIN_FILENO, &c, 1);
if (c == 'r') {
printf("\n你按下了: r\n");
break;
}
}
set_terminal_mode_standard();
return 0;
}
注意: Linux/macOS的实现比Windows复杂,因为它涉及到终端模式的设置,而不仅仅是简单的缓冲区操作。
| 特性 | flushkey() (DOS/Turbo C) |
现代替代方案 (Windows) | 现代替代方案 (Linux/macOS) |
|---|---|---|---|
| 标准性 | 非标准,平台特定 | 非标准,但使用标准API | 非标准,使用系统调用 |
| 作用 | 清空键盘缓冲区 | 清空键盘缓冲区 | 清空标准输入缓冲区 |
| 头文件 | <conio.h> |
<conio.h> 或 <windows.h> |
<unistd.h>, <termios.h>, <sys/select.h> |
| 方法 | 直接调用函数 | while(kbhit()) getch(); 或 ReadConsoleInput |
select() + read() 循环 |
| 关键点 | 简单直接,但已过时 | 方法简单,兼容性好 | 需要处理终端模式,较复杂 |
flushkey 是一个历史遗留函数,如果你正在维护旧的DOS代码,你可能会遇到它,在新的C语言项目中,你应该根据你运行的操作系统,采用上面提到的现代替代方案来实现“清空键盘输入”的功能,对于跨平台需求,推荐使用 kbhit() 和 getch() 的组合,因为它在Windows(通过MinGW等)和许多类Unix系统上都能工作。
