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

C++定时器按空格键暂停时先额外加1秒的问题求助

定时器暂停时额外增加1秒的问题

我写了一个定时器,预期按下空格键就暂停,再次按恢复;或者通过NextStep()退出。但实际按下空格键时,定时器会先额外跳1秒才暂停,比如:

01sec
02sec
按下空格键
03sec(额外+1秒)
定时器暂停

另外执行NextStep()的逻辑是正常的,没有延迟。我试了好几种改写方式都没解决这个问题。

定时器代码

#pragma once

#include <chrono>
#include <iostream>
#include <string>
#include <thread>
#include <stdlib.h>
#include <iomanip>
#include <math.h>
#include <windows.h>
#include <conio.h>
#include <thread>


using namespace std;



void NextStep();
bool pause = false;
bool stop = false; 



void wait(int milliseconds)
{
    int counter = 0;

    while (pause) {
        char ch = _getch();
        if (ch == ' ')
        {
            pause = !pause;
        }
        else if (ch == 27)
        {
            cout << "\033c";
            NextStep();
            stop = true;

        }
    }


    while (counter < milliseconds && !stop)
    {


        if (pause) {
            continue;
        }

        if (pause == false) {
            this_thread::sleep_for(chrono::milliseconds(1));
            counter++;
        }
    }

}


void timer() 
{
    int seconds = 0;
    int minutes = 0;
    int hours = 0;

    
    while (true) 
    {

        cout << "\033c";
        cout << setfill(' ') << setw(55) << "    Timer   \n";
        cout << "                                          ";
        cout << setfill('0') << setw(2) << hours << "h ";
        cout << setfill('0') << setw(2) << minutes << "min ";
        cout << setfill('0') << setw(2) << seconds << "sec ";
        wait(60);

        seconds++;

        if (seconds == 60) {
            minutes++;
            seconds = 0;
        }
        else if (minutes == 60)
        {
            hours++;
            minutes = 0;
            seconds = 0; 
        }
        if (_kbhit())
        {
            char ch = _getch();
            if (ch == ' ')
            {
                pause = !pause;
            }
            else if (ch == 27)
            {
                cout << "\033c";
                NextStep();
                stop = true;
                break;
            }
        }
    }

}

NextStep()函数代码

void NextStep()
{
    string option;
    correct = false; 
    cout << "\033c";
    cout << "Loading...";
    Sleep(1300);
    cout << "\033c";
    cout << "What would you like to do next?" << endl;
    cout << "" << endl;
    cout << "To change your password TYPE: password" << endl;
    cout << "To use a calculator TYPE: calculator" << endl; 
    cout << "To use a timer TYPE: timer" << endl; 
    cout << "" << endl;
    cout << "Type your choice: ";
    UserInput();

}

问题原因

核心问题出在timer()的执行顺序和重复的按键检测逻辑:

  1. 当前逻辑是先显示时间 → 等待 → 强制加1秒 → 再检测按键,所以按下空格暂停时,wait()执行完后已经触发了seconds++,导致多跳1秒才进入暂停。
  2. timer()和wait()里都有按键检测,逻辑重复,容易出现状态不同步的问题。
  3. 额外隐藏问题:wait(60)是等待60毫秒,和定时器1秒更新的预期不符,这会导致时间更新频率异常。

修复方案

修改后的完整代码

#pragma once

#include <chrono>
#include <iostream>
#include <string>
#include <thread>
#include <stdlib.h>
#include <iomanip>
#include <math.h>
#include <windows.h>
#include <conio.h>
#include <thread>


using namespace std;

void NextStep();
bool pause = false;
bool stop = false; 
bool shouldIncrement = false; // 标记是否需要更新时间


void wait(int milliseconds)
{
    int counter = 0;
    shouldIncrement = true; // 默认允许更新时间

    // 处理初始暂停状态
    while (pause && !stop) {
        char ch = _getch();
        if (ch == ' ')
        {
            pause = !pause;
            shouldIncrement = false; // 恢复时不立即跳秒
        }
        else if (ch == 27)
        {
            cout << "\033c";
            NextStep();
            stop = true;
            shouldIncrement = false;
            return;
        }
    }

    // 正常计时等待
    while (counter < milliseconds && !stop)
    {
        if (pause) {
            shouldIncrement = false;
            // 进入暂停循环,等待按键恢复或退出
            while (pause && !stop) {
                char ch = _getch();
                if (ch == ' ')
                {
                    pause = !pause;
                    shouldIncrement = false;
                }
                else if (ch == 27)
                {
                    cout << "\033c";
                    NextStep();
                    stop = true;
                    shouldIncrement = false;
                    return;
                }
            }
            if (stop) break;
        }

        this_thread::sleep_for(chrono::milliseconds(1));
        counter++;
    }
}


void timer() 
{
    int seconds = 0;
    int minutes = 0;
    int hours = 0;

    while (true) 
    {
        if (stop) break;

        // 显示当前时间
        cout << "\033c";
        cout << setfill(' ') << setw(55) << "    Timer   \n";
        cout << "                                          ";
        cout << setfill('0') << setw(2) << hours << "h ";
        cout << setfill('0') << setw(2) << minutes << "min ";
        cout << setfill('0') << setw(2) << seconds << "sec ";
        
        // 等待1秒(修正原60毫秒的错误)
        wait(1000);

        // 根据标记决定是否更新时间,避免暂停时误加秒
        if (shouldIncrement && !stop) {
            seconds++;

            if (seconds == 60) {
                minutes++;
                seconds = 0;
            }
            if (minutes == 60)
            {
                hours++;
                minutes = 0;
                seconds = 0; 
            }
        }
    }
}

关键修改点

  1. 把wait(60)改成wait(1000),对应1秒的计时间隔,符合定时器预期。
  2. 新增shouldIncrement标记,控制等待结束后是否更新时间,避免暂停触发时误加秒。
  3. 统一按键检测逻辑到wait()函数中,删除timer()里的重复检测,避免状态不同步。
  4. 优化暂停状态的处理逻辑,确保按下空格后立即进入暂停,不会触发时间更新。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.31 17:25:30