我想放慢一段时间,只需要一个命令,而不是程序 - 初学者级别 - C ++

I want to slow down for a while just one command and not the program - beginner level - C ++

我想创建一个带秒数的钥匙计数器。我试过了,但它减慢了程序的速度,而不仅仅是秒。

#include <iostream>
#include <Windows.h>
#include <conio.h>
using namespace std;

int x = 1;
int secs = 0;
int clicks = 0;


int main() {
    while (true) {
        if (x == 1) {
            secs++;
            Sleep(1000);
            system("CLS");
            cout << "Clicks: " << clicks << "             Time: " << secs;
            x = 2;
        }
        else if (2 == x) {
            _getch();
            clicks++;
            system("CLS");
            cout << "Clicks: " << clicks << "             Time: " << secs;
            x = 1;
        }
    }
}

您似乎希望Sleep function to not block the entire program while waiting for the timer, but to continue processing keyboard input while waiting for the timer. Also, you seem to want the getch函数在等待键盘输入时不阻塞整个程序,而是在等待键盘输入时继续处理定时器。但是,这不是这些功能的工作方式。这两个函数将永远阻塞,直到它们正在等待的特定类型的事件发生。

您想要的是一个能够同时等待多种不同类型事件的函数。该函数应仅在发生这些事件之一之前阻塞。一旦此类事件发生,该函数应立即 return 并指定发生的事件类型,即它是定时器事件还是键盘输入事件。这样,事件就可以立即处理了。

通常,您可以使用函数 WaitForMultipleObjects for this purpose. However, in this case, the function WaitForSingleObject 就足够了,因为该函数将允许您指定超时间隔以及要等待的对象句柄。这样,您就可以在计时器和对象句柄上等待键盘输入。

不幸的是,根据我的测试,在控制台的输入句柄上使用 WaitForSingleObject 只有在使用 low-level 控制台 API 函数(例如 ReadConsoleInput. It seems it cannot reliably predict whether kbhit and getch will work, and it also won't work reliably with ReadConsole.

我相信这个程序可以完成你想要的:

#include <Windows.h>
#include <iostream>
#include <cstdio>

int main()
{
    HANDLE hStdin = INVALID_HANDLE_VALUE;
    ULONGLONG ullStartTime;

    //counter of the number of times a keypress was registered
    int num_keypresses = 0;

    //get input handle
    hStdin= GetStdHandle( STD_INPUT_HANDLE );
    if ( hStdin == INVALID_HANDLE_VALUE )
    {
        std::cerr << "error opening input handle!\n" << std::flush;
        exit( EXIT_FAILURE );
    }

    //remember time that program started
    ullStartTime = GetTickCount64();

    for (;;) //infinite loop, equivalent to while(1)
    {
        ULONGLONG ullElapsedTime = GetTickCount64() - ullStartTime;

        int seconds   = (int) ( ullElapsedTime / 1000 );
        int remainder = (int) ( ullElapsedTime % 1000 );

        //round up to next second, if appropriate
        if ( remainder >= 500 )
        {
            seconds++;
            remainder -= 1000;
        }

        //uncomment the folllowing line to clear the screen
        //std::system( "cls" );

        //write data to screen
        std::cout << "Keypresses: " << num_keypresses << "     Time: " << seconds << " seconds\n" << std::flush;

        //wait for either a keypress to occur, or for a timeout to occur
        switch ( WaitForSingleObject( hStdin, 1000 - remainder ) )
        {
            case WAIT_OBJECT_0:
            {
                DWORD dwRead;
                INPUT_RECORD ir;

                //console input event occurred, so read it
                if ( !ReadConsoleInput( hStdin, &ir, 1, &dwRead ) || dwRead != 1 )
                {
                    std::cerr << "error reading input!\n" << std::flush;
                    std::exit( EXIT_FAILURE );
                }

                if ( ir.EventType == KEY_EVENT && ir.Event.KeyEvent.bKeyDown )
                {
                    num_keypresses += ir.Event.KeyEvent.wRepeatCount;
                }
                break;
            }
            case WAIT_TIMEOUT:
            {
                //timeout occurred
                break;
            }
            default:
            {
                std::cerr << "unexpected error!\n" << std::flush;
                std::exit( EXIT_FAILURE );
            }
        }
    }
}

如果我在开始按键之前等待大约 5 秒,然后按几下,那么我得到的输出如下:

Keypresses: 0     Time: 0 seconds
Keypresses: 0     Time: 1 seconds
Keypresses: 0     Time: 2 seconds
Keypresses: 0     Time: 3 seconds
Keypresses: 0     Time: 4 seconds
Keypresses: 0     Time: 5 seconds
Keypresses: 1     Time: 6 seconds
Keypresses: 1     Time: 6 seconds
Keypresses: 2     Time: 7 seconds
Keypresses: 2     Time: 7 seconds
Keypresses: 2     Time: 8 seconds
Keypresses: 3     Time: 9 seconds
Keypresses: 3     Time: 9 seconds
Keypresses: 4     Time: 10 seconds
Keypresses: 4     Time: 10 seconds
Keypresses: 4     Time: 11 seconds
Keypresses: 5     Time: 11 seconds
Keypresses: 5     Time: 11 seconds
Keypresses: 5     Time: 12 seconds
Keypresses: 6     Time: 12 seconds
Keypresses: 6     Time: 13 seconds
Keypresses: 6     Time: 14 seconds
Keypresses: 7     Time: 15 seconds
Keypresses: 7     Time: 15 seconds
Keypresses: 7     Time: 16 seconds
Keypresses: 7     Time: 17 seconds

在您的原始程序中,您使用 std::system("cls"); 来清除屏幕,而不是每次都打印一个新行。在我的程序中,我没有清除屏幕,但是,您可以取消注释 std::system("cls"); 行,它应该可以工作。我已经把它放在正确的地方了。但是请注意,使用 Microsoft 官方文档中的 std::system is not recommended. See this page 以获得更好的替代方案。