You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何修改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;
}

关键修改点说明

  1. 循环终止条件从c != 'e' && c != 'E'改为c != 27(ESC键的ASCII码值)
  2. 替换输入方式:Windows用_getch(),Linux/macOS修改终端属性后用getchar(),实现无需回车读取按键
  3. 更新提示信息,告知用户按ESC键退出
  4. 在switch分支中添加case 27:捕获ESC键

内容的提问来源于stack exchange,提问作者Faham Sultan

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.03 14:05:26