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

C#实时读取特定按键问题:牙刷模拟程序无法响应PowerButton输入

解决牙刷模拟程序无法读取'p'键的问题

你的代码核心问题是模式切换后的死循环阻塞了输入读取:当你切换到某个模式(比如Sensitive)后,进入的while (powerButtonCount == 2 && optionButtonCount == 1)是个没有退出条件的死循环——它只会一直输出刷牙提示,完全不会去监听新的按键输入,所以按'p'根本不会被程序捕获。另外电源键的逻辑也有漏洞,没有处理"按第二次p开始刷牙、第三次p关机"的完整流程。

下面是修正后的代码,同时优化了逻辑结构,更符合真实牙刷的操作逻辑:

Console.WriteLine("Hello!");
int powerButtonCount = 0;
int optionButtonCount = 0;
bool isBrushing = false; // 标记是否处于刷牙状态

// 主循环:持续监听用户按键
while (true)
{
    // 读取按键,true表示不在控制台显示按下的字符,界面更整洁
    var pressedKey = Console.ReadKey(true);

    if (pressedKey.KeyChar == 'p')
    {
        powerButtonCount++;
        switch (powerButtonCount)
        {
            case 1:
                // 第一次按p:开机,重置模式计数
                Console.WriteLine("\n已开机,按'o'切换模式,按'p'开始刷牙");
                optionButtonCount = 0;
                isBrushing = false;
                break;
            case 2:
                // 第二次按p:检查是否已选模式,确认后开始刷牙
                if (optionButtonCount == 0)
                {
                    Console.WriteLine("\n请先按'o'选择模式!");
                    powerButtonCount--; // 回退到开机状态
                    break;
                }
                Console.WriteLine($"\n开始{GetModeName(optionButtonCount)}模式刷牙,按'p'停止");
                isBrushing = true;
                break;
            case 3:
                // 第三次按p:关机退出程序
                powerButtonCount = 0;
                optionButtonCount = 0;
                isBrushing = false;
                Console.WriteLine("\nGood Bye!");
                return; // 终止程序
        }
    }
    else if (pressedKey.KeyChar == 'o' && powerButtonCount == 1 && !isBrushing)
    {
        // 只有在开机且未刷牙时,才允许切换模式
        optionButtonCount++;
        if (optionButtonCount > 5) optionButtonCount = 1; // 模式循环切换(超过5回到1)
        Console.WriteLine($"\n当前模式:{GetModeName(optionButtonCount)}");
    }

    // 刷牙状态下的循环输出,同时保留按键监听能力
    if (isBrushing)
    {
        System.Threading.Thread.Sleep(1000); // 模拟刷牙间隔,每秒输出一次
        Console.WriteLine($"正在{GetModeName(optionButtonCount)}模式刷牙...");
    }
}

// 提取模式名称的方法,避免重复代码
static string GetModeName(int count)
{
    return count switch
    {
        1 => "Sensitive",
        2 => "Gum Care",
        3 => "Intense",
        4 => "Daily Clean",
        5 => "Whiten",
        _ => "未知"
    };
}

关键改动说明

  1. 用主while(true)循环统一监听按键,避免程序卡在某个分支里无法响应输入
  2. 新增isBrushing变量标记状态,清晰区分"待机选模式"和"刷牙中"两种场景
  3. 完善电源键逻辑:分三次按p的不同行为(开机/开始刷牙/关机)
  4. 模式键仅在开机且未刷牙时生效,避免刷牙时误触切换模式
  5. 刷牙状态下加入延迟,模拟真实刷牙节奏,且每次输出后会回到主循环监听按键,确保按p能立即停止刷牙
  6. 提取GetModeName方法,减少重复代码,后续修改模式更方便

新手避坑提示

  • 不要写没有退出条件的while循环,除非是故意做持续监听的场景(比如服务器)
  • 处理用户输入时,要确保程序始终回到输入监听的逻辑,不能让代码卡在某个无交互的循环里
  • 用状态变量(比如isBrushing)判断当前程序状态,比单纯靠计数判断更清晰,后续扩展功能也更简单

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.25 21:36:29