如何修改C++收费站模拟代码实现按ESC键结束循环?
如何修改C++代码实现按ESC键终止收费站模拟程序并输出统计数据
我在DS&OOP课程的作业中实现了一个桥梁收费站模拟系统,需要统计:
- 过往车辆数
- 缴费车辆数
- 总过往车辆数及总收费金额
用户操作要求是按p记录缴费车辆、n记录未缴费车辆,按ESC键结束程序并输出统计数据。但我目前用e键替代了ESC键,现有代码如下:
int main() { tollBooth t; char c = 0; while (c != 'e' && c != 'E') { cout << "Choose:\n'p' paying car \n'n' nonpaying car \n'e' exit \n"; cin >> c; switch (c) { case 'p': case 'P': t.payingCar(); break; case 'n': case 'N': t.nopayCar(); break; case 'e': case 'E': break; default: cout << "Invalid choice, try again." << endl; break; } } t.Display(); return 0; }
现在想修改代码,实现按ESC键终止程序并输出统计数据,该怎么做?
要实现按ESC键终止程序,核心问题是cin >> c会等待用户输入并按下回车,无法直接捕获ESC这种特殊按键。需要改用能直接读取键盘输入(无需回车)的函数,并且匹配ESC键的ASCII码(值为27)。以下分两种常见平台给出修改方案:
Windows平台方案
使用_getch()函数(需包含<conio.h>头文件),它可以直接读取单个按键输入,无需回车:
#include <conio.h> // 引入_getch()所需头文件 int main() { tollBooth t; char c = 0; while (c != 27) // ESC键的ASCII码是27 { cout << "Choose:\n'p' paying car \n'n' nonpaying car \nESC to exit \n"; c = _getch(); // 直接读取按键,无需回车 switch (c) { case 'p': case 'P': t.payingCar(); break; case 'n': case 'N': t.nopayCar(); break; case 27: // 捕获ESC键 break; default: cout << "Invalid choice, try again." << endl; break; } } t.Display(); return 0; }
Linux/macOS平台方案
在类Unix系统中,需要先修改终端属性,让getchar()无需等待回车就能读取输入,再捕获ESC键:
#include <termios.h> #include <unistd.h> // 辅助函数:设置终端为无缓冲模式 void setTerminalRaw() { struct termios term; tcgetattr(STDIN_FILENO, &term); term.c_lflag &= ~(ICANON | ECHO); // 关闭行缓冲和回显 tcsetattr(STDIN_FILENO, TCSANOW, &term); } // 辅助函数:恢复终端默认模式 void restoreTerminal() { struct termios term; tcgetattr(STDIN_FILENO, &term); term.c_lflag |= ICANON | ECHO; tcsetattr(STDIN_FILENO, TCSANOW, &term); } int main() { tollBooth t; char c = 0; setTerminalRaw(); // 设置终端为无缓冲模式 while (c != 27) { cout << "Choose:\n'p' paying car \n'n' nonpaying car \nESC to exit \n"; c = getchar(); switch (c) { case 'p': case 'P': t.payingCar(); break; case 'n': case 'N': t.nopayCar(); break; case 27: break; default: cout << "Invalid choice, try again." << endl; break; } } restoreTerminal(); // 恢复终端默认设置 t.Display(); return 0; }
关键修改点说明
- 循环终止条件从
c != 'e' && c != 'E'改为c != 27(ESC键的ASCII码值) - 替换输入方式:Windows用
_getch(),Linux/macOS修改终端属性后用getchar(),实现无需回车读取按键 - 更新提示信息,告知用户按ESC键退出
- 在switch分支中添加
case 27:捕获ESC键
内容的提问来源于stack exchange,提问作者Faham Sultan
相关产品推荐
相关产品推荐

