【问题标题】:How to set time limit for user to input char in C?如何设置用户在 C 中输入字符的时间限制?
【发布时间】:2015-01-04 14:21:26
【问题描述】:

首先,对不起我的英语不好。我正在使用 windows.h 中包含的 GetTickCount() 函数和 conio.h 中包含的 getch() 函数。

我真正想要的是给用户一个输入字符的时间限制。如果超过时间限制,程序继续执行,跳过等待用户输入字符。

char ch='A';
DWORD start_time, check_time;

start_time=GetTickCount();
check_time=start+500; //GetTickCount returns time in miliseconds, so I add 500 to wait input for half a second.

while (check_time>GetTickCount()) {
ch=getchar();
}

//do stuff with char with initial value of 'A' if user didn't enter another char during 500ms of wait.

但是 getchar() 会停止执行程序并无限期地等待用户输入 char。是否有一个简单的解决方案可以绕过此等待,并在 500 毫秒过去后继续?

编辑:

根据您的提示,我写了这个并且它有效!谢谢各位!

while (!kbhit()&&(check_time>GetTickCount()))
    {
        if (kbhit())
        {
            ch=getch();
            break;
        }
    }

【问题讨论】:

  • 你必须使用另一个函数来读取标准输入,比如ioctl,也可以看到stackoverflow.com/questions/10004895/…
  • 在 unix 上,你有 select() 来完成这项工作。在 Windows 上,我不知道。
  • This link 展示了如何做到这一点
  • @CharlieBurns - GetAsyncKeyState() 在 Windows 中用于检测特定键。不确定它在这里是否完美,但非常适合设置特定键,查看它何时被击中。
  • 在你的链接中有一个叫做 kbdhit() 的东西可能对他有用。

标签: c windows input time limit


【解决方案1】:

Windows 解决方案 使用 GetTickCount()GetAsyncKeyState(...)

此方法使用非阻塞 Windows API 函数 GetAsyncKeyState(),带有 GetTickCount(我没有 GetTimeTick)但这可以很容易地更改为 @987654323 @为您的系统。

keyPressed(...) 查看 256 个键中的每一个,包括键盘的虚拟键,如果按下任何键,则返回 true:

#include <windows.h>  

BOOL keyPressed(char *keys)
{
    for(int i = 0; i<256; i++)
        if(GetAsyncKeyState(i) >> 8) return 1;
    return 0;   
}    

测试 keyPressed 功能:

#define TIME_LIMIT 10

int main(void)
{
    int c=0;
    char *key;  
    DWORD Start, Duration=0; //unsigned long int

    key = calloc(256, 1);

    Start = GetTickCount();

    memset(key, 0, 256);
    while((Duration < MAX_TIME)&&(!keyPressed(key))) // \n character
    {
        Duration = GetTickCount() - Start;
    }
    if (Duration < MAX_TIME) printf("in-time\n");
    else printf("Out of time\n");

    getchar();

    free (key);
    return 0;
}

【讨论】:

    【解决方案2】:

    正如 Charlie Burns 所提议的,conio 中的 kbhit 函数完全符合您的要求:看起来像是按下了键。

    你可以这样做:

    DWORD start_time, check_time;
    
    start_time=GetTickTime();
    check_time=start+500; //GetTickTime returns time in miliseconds, so I add 500 to wait input for half a second.
    char ch = 0;
    char hit =0
    
    while (check_time>GetTickTime()) {
        if (_kbhit()) {
            hit = 1;
            ch = _getch();
            if (ch  == 0) ch = _getch() // an arrow key was pressed
            break;
        }
    }
    // if hit == 0 we got a timout, else ch is the code of the key
    

    注意:未经测试...

    【讨论】:

    • 是的,这解决了问题!我得到了类似的解决方案,但我认为您在某些情况下可能会更好。出于某种原因,我不允许对您的帖子进行投票。
    猜你喜欢
    • 1970-01-01
    • 2022-12-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多