C++如何清空输入缓冲区?按回车选中菜单后函数重复调用怎么解决
问题原因
- 你使用的
GetAsyncKeyState函数返回值包含按键的历史状态信息,仅判断!= 0时可能检测到已经触发过的按键按下记录,而非当前实时按下的状态。 - 按下回车键触发对应功能函数时,按键处于按下状态,功能执行完成后按键还未松开,回到按键检测循环时会再次检测到回车键按下,导致重复触发功能。
- 控制台输入缓冲区残留的按键输入消息没有被清空,也会导致重复触发。
解决办法
修改按键检测逻辑,增加按键释放等待和输入缓冲区清空操作,具体修改点如下:
- 修改按键状态判断逻辑,使用
& 0x8000判断按键当前是否处于按下状态,避免历史状态干扰。 - 检测到按键按下后,先等待对应按键完全释放,再执行后续逻辑,避免一次按动多次触发。
- 功能函数执行完成后,清空控制台输入缓冲区,清除残留的按键消息。
修改后完整代码如下:
int menu(){ string Menu[6] = {"Insert Student Record", "Delete Student Record", "Update Student Record", "Display All Student Record", "Exit & Save"}; int pointer = 0; HANDLE hConsole = GetStdHandle(STD_OUTPUT_HANDLE); HANDLE hInput = GetStdHandle(STD_INPUT_HANDLE); // 新增获取输入句柄 while(true){ system("cls"); SetColor(11);cout<<"\n\tPlease navigate to the menu using up-down arrow keys"<<endl;SetColor(15); for(int i=0; i<5; ++i){ if(i==pointer){ SetConsoleTextAttribute(hConsole, 159); cout << Menu[i] << endl; }else{ SetConsoleTextAttribute(hConsole, 15); cout << Menu[i] << endl; } SetConsoleTextAttribute(hConsole, 15); } while(true){ // 修改按键判断逻辑,用&0x8000判断当前是否按下 if(GetAsyncKeyState(VK_UP) & 0x8000){ --pointer; if(pointer == -1){ pointer = 4; } // 等待方向键释放,避免一次按动跳过多项 while(GetAsyncKeyState(VK_UP) & 0x8000); break; }else if(GetAsyncKeyState(VK_DOWN) & 0x8000){ ++pointer; if(pointer == 5){ pointer = 0; } while(GetAsyncKeyState(VK_DOWN) & 0x8000); break; }else if(GetAsyncKeyState(VK_RETURN) & 0x8000){ // 先等待回车键完全释放 while(GetAsyncKeyState(VK_RETURN) & 0x8000); // 清空输入缓冲区残留消息 FlushConsoleInputBuffer(hInput); switch(pointer){ case 0: { system("cls"); insertMode(); }break; case 1: { system("cls"); deleteMode(); }break; case 2: { system("cls"); updateMode(); cout<<"\n\t"; }break; case 3: { system("cls"); studList.display(); cout<<"\n\t";system("pause"); }break; case 4: { system("cls"); exitMessage(); studList.save(); exit(0); } break; } // 功能执行完成后再次清空输入缓冲,避免功能执行期间的按键影响菜单 FlushConsoleInputBuffer(hInput); break; } } Sleep(150); } }
内容的提问来源于stack exchange,提问作者Emilia King
相关产品推荐
相关产品推荐

