kbhit()函数与getch()函数(键盘缓冲)

时间:2022-01-26 07:01:39
  额,自己查资料,知道getch是不显示的读一个按键,kbhit是只检测是否有键按下,返回的是一个整型数,那我就想问下,kbhit函数返回的值与当时按下的键有什么关系?
  最后,关于两个函数是如何实现的,哪位大虾给个点拨?让我看网上看资料的时候容易理解一些(是和键盘缓冲有关的吗?)

10 个解决方案

#1


这两个函数没有缓冲,是立即得到结果的

#2


getch函数没有缓冲
kbhit函数检查缓冲
kbhit returns a nonzero value if a key has been pressed. Otherwise, it returns 0.
If the function returns a nonzero value, a keystroke is waiting in the buffer. 

#3


也就是说,如果缓冲里有东西,它就会返回一个非0的数,那会不会产生即使没有按键,kbhit()函数仍然返回一个非0数的情况?

#4


引用 3 楼 only_lonely 的回复:
也就是说,如果缓冲里有东西,它就会返回一个非0的数,那会不会产生即使没有按键,kbhit()函数仍然返回一个非0数的情况?

有可能,如果输入时还剩下未取出的字符在里面,就会

#5


引用楼主 only_lonely 的帖子:
  额,自己查资料,知道getch是不显示的读一个按键,kbhit是只检测是否有键按下,返回的是一个整型数,那我就想问下,kbhit函数返回的值与当时按下的键有什么关系? 
  最后,关于两个函数是如何实现的,哪位大虾给个点拨?让我看网上看资料的时候容易理解一些(是和键盘缓冲有关的吗?) 

getch 从控制台无回显地取一个字符  kbhit 检查当前按下的键 

#include <conio.h> 

int main(void) 

   cprintf("Press any key to continue:"); 
   while (!kbhit()) /* do nothing */ ; //用返回值来判断 逻辑关系 
   cprintf("\r\nA key was pressed...\r\n"); 
   return 0; 



没有你说的键盘缓冲 
想看函数实现 就源代码吧

#6


引用 4 楼 lbh2001 的回复:
引用 3 楼 only_lonely 的回复:
也就是说,如果缓冲里有东西,它就会返回一个非0的数,那会不会产生即使没有按键,kbhit()函数仍然返回一个非0数的情况? 
 
有可能,如果输入时还剩下未取出的字符在里面,就会

谢谢

#7


引用 4 楼 lbh2001 的回复:
引用 3 楼 only_lonely 的回复:
也就是说,如果缓冲里有东西,它就会返回一个非0的数,那会不会产生即使没有按键,kbhit()函数仍然返回一个非0数的情况? 
 
有可能,如果输入时还剩下未取出的字符在里面,就会

难怪清空键盘的缓存要用
while(!kbhit())
getch();
来实现了

#8


额,是while(kbhit())
      getch();
是我错,太激动···

#9


kbhit 返回的只是0或1,代表是否有按键发生,其内部实现大致如下:


signed int __cdecl _kbhit_nolock()
{
  char ST10_1_0; // ST10_1@0
  void *v2; // eax@11
  struct _INPUT_RECORD *v3; // ebx@16
  DWORD v4; // edi@20
  int v5; // esi@23
  int  s; // [sp+1Ch] [bp+0h]@1
  unsigned int v7; // [sp+18h] [bp-4h]@1
  signed int v8; // [sp+Ch] [bp-10h]@1
  DWORD nLength; // [sp+14h] [bp-8h]@6
  DWORD NumberOfEventsRead; // [sp+10h] [bp-Ch]@19

  v7 = (unsigned int)& s ^ dword_40D420;
  v8 = 0;
  if ( dword_40DF70 != -1 )
    return 1;
  if ( hConsoleHandle == (HANDLE)-2 )
    __initconin();
  if ( hConsoleHandle == (HANDLE)-1 || !GetNumberOfConsoleInputEvents(hConsoleHandle, &nLength) || !nLength )
    return 0;
  if ( nLength && 0xFFFFFFE0 / nLength >= 0x14 )
  {
    if ( 20 * nLength + 8 > 0x400 )
    {
      v2 = malloc(20 * nLength + 8);
      if ( v2 )
      {
        *(_DWORD *)v2 = 56797;
        goto LABEL_15;
      }
    }
    else
    {
      _alloca_probe_16(20 * nLength + 8, ST10_1_0);
      v2 = &ST10_1_0;
      if ( &ST10_1_0 )
      {
        *(_DWORD *)&ST10_1_0 = 52428;
LABEL_15:
        v2 = (char *)v2 + 8;
        goto LABEL_16;
      }
    }
LABEL_16:
    v3 = (struct _INPUT_RECORD *)v2;
    goto LABEL_18;
  }
  v3 = 0;
LABEL_18:
  if ( !v3 )
    return 0;
  if ( PeekConsoleInputA(hConsoleHandle, v3, nLength, &NumberOfEventsRead) )
  {
    v4 = NumberOfEventsRead;
    if ( NumberOfEventsRead )
    {
      if ( NumberOfEventsRead <= nLength )
      {
        if ( NumberOfEventsRead )
        {
          v5 = (int)&v3->Event;
          do
          {
            if ( *(_WORD *)(v5 - 4) == 1 )
            {
              if ( *(_DWORD *)v5 )
              {
                if ( *(_BYTE *)(v5 + 10) || _getextendedkeycode(v5) )
                  v8 = 1;
              }
            }
            --v4;
            v5 += 20;
            NumberOfEventsRead = v4;
          }
          while ( v4 );
        }
      }
    }
  }
  _freea(v3);
  return v8;
}

//其中__initconin()函数为
HANDLE __cdecl __initconin()
{
  HANDLE result; // eax@1

  result = CreateFileA("CONIN$", 0xC0000000u, 3u, 0, 3u, 0, 0);
  hConsoleHandle = result;
  return result;
}

#10


kbhit()如果没按键返回的是0.

#1


这两个函数没有缓冲,是立即得到结果的

#2


getch函数没有缓冲
kbhit函数检查缓冲
kbhit returns a nonzero value if a key has been pressed. Otherwise, it returns 0.
If the function returns a nonzero value, a keystroke is waiting in the buffer. 

#3


也就是说,如果缓冲里有东西,它就会返回一个非0的数,那会不会产生即使没有按键,kbhit()函数仍然返回一个非0数的情况?

#4


引用 3 楼 only_lonely 的回复:
也就是说,如果缓冲里有东西,它就会返回一个非0的数,那会不会产生即使没有按键,kbhit()函数仍然返回一个非0数的情况?

有可能,如果输入时还剩下未取出的字符在里面,就会

#5


引用楼主 only_lonely 的帖子:
  额,自己查资料,知道getch是不显示的读一个按键,kbhit是只检测是否有键按下,返回的是一个整型数,那我就想问下,kbhit函数返回的值与当时按下的键有什么关系? 
  最后,关于两个函数是如何实现的,哪位大虾给个点拨?让我看网上看资料的时候容易理解一些(是和键盘缓冲有关的吗?) 

getch 从控制台无回显地取一个字符  kbhit 检查当前按下的键 

#include <conio.h> 

int main(void) 

   cprintf("Press any key to continue:"); 
   while (!kbhit()) /* do nothing */ ; //用返回值来判断 逻辑关系 
   cprintf("\r\nA key was pressed...\r\n"); 
   return 0; 



没有你说的键盘缓冲 
想看函数实现 就源代码吧

#6


引用 4 楼 lbh2001 的回复:
引用 3 楼 only_lonely 的回复:
也就是说,如果缓冲里有东西,它就会返回一个非0的数,那会不会产生即使没有按键,kbhit()函数仍然返回一个非0数的情况? 
 
有可能,如果输入时还剩下未取出的字符在里面,就会

谢谢

#7


引用 4 楼 lbh2001 的回复:
引用 3 楼 only_lonely 的回复:
也就是说,如果缓冲里有东西,它就会返回一个非0的数,那会不会产生即使没有按键,kbhit()函数仍然返回一个非0数的情况? 
 
有可能,如果输入时还剩下未取出的字符在里面,就会

难怪清空键盘的缓存要用
while(!kbhit())
getch();
来实现了

#8


额,是while(kbhit())
      getch();
是我错,太激动···

#9


kbhit 返回的只是0或1,代表是否有按键发生,其内部实现大致如下:


signed int __cdecl _kbhit_nolock()
{
  char ST10_1_0; // ST10_1@0
  void *v2; // eax@11
  struct _INPUT_RECORD *v3; // ebx@16
  DWORD v4; // edi@20
  int v5; // esi@23
  int  s; // [sp+1Ch] [bp+0h]@1
  unsigned int v7; // [sp+18h] [bp-4h]@1
  signed int v8; // [sp+Ch] [bp-10h]@1
  DWORD nLength; // [sp+14h] [bp-8h]@6
  DWORD NumberOfEventsRead; // [sp+10h] [bp-Ch]@19

  v7 = (unsigned int)& s ^ dword_40D420;
  v8 = 0;
  if ( dword_40DF70 != -1 )
    return 1;
  if ( hConsoleHandle == (HANDLE)-2 )
    __initconin();
  if ( hConsoleHandle == (HANDLE)-1 || !GetNumberOfConsoleInputEvents(hConsoleHandle, &nLength) || !nLength )
    return 0;
  if ( nLength && 0xFFFFFFE0 / nLength >= 0x14 )
  {
    if ( 20 * nLength + 8 > 0x400 )
    {
      v2 = malloc(20 * nLength + 8);
      if ( v2 )
      {
        *(_DWORD *)v2 = 56797;
        goto LABEL_15;
      }
    }
    else
    {
      _alloca_probe_16(20 * nLength + 8, ST10_1_0);
      v2 = &ST10_1_0;
      if ( &ST10_1_0 )
      {
        *(_DWORD *)&ST10_1_0 = 52428;
LABEL_15:
        v2 = (char *)v2 + 8;
        goto LABEL_16;
      }
    }
LABEL_16:
    v3 = (struct _INPUT_RECORD *)v2;
    goto LABEL_18;
  }
  v3 = 0;
LABEL_18:
  if ( !v3 )
    return 0;
  if ( PeekConsoleInputA(hConsoleHandle, v3, nLength, &NumberOfEventsRead) )
  {
    v4 = NumberOfEventsRead;
    if ( NumberOfEventsRead )
    {
      if ( NumberOfEventsRead <= nLength )
      {
        if ( NumberOfEventsRead )
        {
          v5 = (int)&v3->Event;
          do
          {
            if ( *(_WORD *)(v5 - 4) == 1 )
            {
              if ( *(_DWORD *)v5 )
              {
                if ( *(_BYTE *)(v5 + 10) || _getextendedkeycode(v5) )
                  v8 = 1;
              }
            }
            --v4;
            v5 += 20;
            NumberOfEventsRead = v4;
          }
          while ( v4 );
        }
      }
    }
  }
  _freea(v3);
  return v8;
}

//其中__initconin()函数为
HANDLE __cdecl __initconin()
{
  HANDLE result; // eax@1

  result = CreateFileA("CONIN$", 0xC0000000u, 3u, 0, 3u, 0, 0);
  hConsoleHandle = result;
  return result;
}

#10


kbhit()如果没按键返回的是0.