I have been testing some things with kbhit() and have found an odd behavior with a delayed infinite loop. In this code sample I have the loop delayed to run 30 times every second.
#include <stdio.h>
#include <stdlib.h>
#include <windows.h>
#include <conio.h>
_Bool IsKeyDown(char c)
{
if(kbhit())
{
char ch1 = getch();
if(ch1 == c)
return 1;
}
return 0;
}
/*
*
*/
int main(int argc, char** argv) {
while(1)
{
if(IsKeyDown('a'))
{
printf("HELLO\n");
}
if(IsKeyDown('b'))
{
printf("HI\n");
}
Sleep(1000 / 30);
}
return (EXIT_SUCCESS);
}
The issue is, though the first if statement in the loop works fine, the second if statement barely functions. If you hold down the 'a' key in this example, HELLO is printed indefinitely. If you hold down the 'b' key, HI is barely ever printed, if ever.
Why is this behavior occurring?
This happens because your
IsKeyDown
has a side effect of consuming the next character from the buffer whenkbhit
returnstrue
. Since you callIsKeyDown
twice in a row, the first invocation "eats up" the'b'
, so when it's time to run the second invocation, there's no data in the buffer.You need to reorganize your code so that
IsKeyDown
is called only once per loop iteration. Your loop should store its return value, and compare that stored value to the characters that you need (i.e.'a'
and'b'
):