I am creating a console application in C. This is a game in which characters are falling down and user has to press that specific key on the keyboard. I don't know how to detect which key is pressed by the user without pausing the falling characters. When I use scanf the Program waits for input and everything pauses. Please help me soon!
- 
                    this is actually interesting .. looking forward to some answers – sukhvir Nov 09 '13 at 11:00
- 
                    http://stackoverflow.com/a/13035523/1119701 – ouah Nov 09 '13 at 11:02
- 
                    Is there any other way to do this without ncurses – sukhvir Nov 09 '13 at 11:03
- 
                    You can try to hook a window-procedure and listen to events. Unlike `scanf` this should not block. – MasterMastic Nov 09 '13 at 11:06
- 
                    You can push the function to get keyboard input to another thread – Shubham Nov 09 '13 at 11:22
- 
                    http://en.wikipedia.org/wiki/Conio.h – hyde Nov 09 '13 at 11:41
3 Answers
There is a function called kbhit() or _kbhit it is in the <conio.h> library it returns true or false depending whether a key was hit. So you can go with something like this:
while (1){
    if ( _kbhit() )
        key_code = _getch();
        // do stuff depending on key_code
    else 
        continue;
Also use getch() or _getch which reads a character directly from the console and not from the buffer. You can read more about conio.h functions here they might be very useful for what you want to do.
Note: conio.h is not a standard library and implementations may vary from compiler to compiler.
 
    
    - 4,423
- 2
- 26
- 52
 
    
    - 2,952
- 3
- 24
- 46
- 
                    with the getch() my game still pause and waits for input. I just don't need to press enter key after entering a char. That is not the problem! – Zain Zafar Nov 09 '13 at 11:50
- 
                    1@zaingz that is the reason you have to use `if ( kbhit() )` so that it "waits" only if something was pressed. But because it was already pressed when it comes to `key_code = getch();` it reads the key that was pressed. – Alexandru Barbarosie Nov 09 '13 at 12:02
- 
                    Thanks a lot...This really helped me. One tip for those who use Visual studio should add underscore "_" in the start of every conio function. i.e : _kbhit() and _getch() – Zain Zafar Nov 09 '13 at 16:59
- 
                    Just to give an update, in ANSI C currently, kbhit() and getch() are deprecated, instead _kbhit() and _getch() are used! Useful answer though :) – Sanket Patel Dec 02 '16 at 01:29
- 
                    @SanketPatel feel free to edit my answer with this information. – Alexandru Barbarosie Dec 02 '16 at 10:20
You may probably look for ncurses
ncurses (new curses) is a programming library that provides an API which allows the programmer to write text-based user interfaces in a terminal-independent manner. It is a toolkit for developing "GUI-like" application software that runs under a terminal emulator.
Also check C/C++: Capture characters from standard input without waiting for enter to be pressed
#include <conio.h>
if (kbhit()!=0) {
    cout<<getch()<<endl;
}
 
    
    - 1
- 1
 
    
    - 168,305
- 31
- 280
- 331
- 
                    Not very sure but if it would have been for graphics implementation then it could be done using SDL – Rahul Tripathi Nov 09 '13 at 11:04
- 
                    ncurses is not feasible. Isn't there any thing in windows.h library? – Zain Zafar Nov 09 '13 at 11:14
- 
                    The equivalent for ncurses in Windows is PDCurses. http://pdcurses.sourceforge.net/ – Rahul Tripathi Nov 09 '13 at 11:17
I think this might be the non-blocking keyboard input you are looking for.
void simple_keyboard_input()  //win32 & conio.h
    {
        if (kbhit())
          {
                KB_code = getch();
                //cout<<"KB_code = "<<KB_code<<"\n";
                switch (KB_code)
                {
                    case KB_ESCAPE:
                        QuitGame=true;
                    break;
                 }//switch
             }//if kb
          }//void
And as for the characters falling down.. here you go.

Code for if you are on Windows:
/* The Matrix  falling numbers */
#include <iostream>
#include <windows.h> 
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <conio.h>
using namespace std;
#define KB_UP 72
#define KB_DOWN 80
#define KB_LEFT 75
#define KB_RIGHT 77
#define KB_ESCAPE 27
#define KB_F8 66
/* Variables*/
char screen_buffer[2000]={' '};
int y_coord[2000]={0};
int x=0, y=0,dy=0;
int XMAX=77;
int YMAX=23;
int KB_code=0;
bool QuitGame=false;
int platformX=35, platformY=23;
/* function prototypes*/
void gotoxy(int x, int y);
void clrscr(void);
void setcolor(WORD color); 
void simple_keyboard_input();  
void draw_falling_numbers();
void draw_platform();
/*  main  */
int main(void)
{
  /* generate random seed */
  srand ( time(NULL) );
  /* generate random number*/
  for(int i=0;i<XMAX;i++) y_coord[i]=   rand() % YMAX;
  while(!QuitGame)
  {
      /* simple keyboard input */
      simple_keyboard_input();
      /* draw falling numbers */
      draw_falling_numbers();
  }
  /* restore text color */
  setcolor(7);
  clrscr( );
  cout<<" \n";
  cout<<" \nPress any key to continue\n";
  cin.ignore();
  cin.get();
   return 0;
}
/* functions  */
void draw_falling_numbers()
{
    for(x=0;x<=XMAX;x++)
    {
        /* generate random number */
        int MatixNumber=rand() % 2 ;
        /* update falling number */
        y_coord[x]=y_coord[x]+1;
        if (y_coord[x]>YMAX) y_coord[x]=0;
        /* draw dark color */
        setcolor(2);
        gotoxy(x ,y_coord[x]-1); cout<<"  "<<MatixNumber<<"   ";
        /* draw light color */
        setcolor(10);
        gotoxy(x ,y_coord[x]); cout<<"  "<<MatixNumber<<"   ";
    }
    /* wait some milliseconds */
    Sleep(50);
    //clrscr( );
}
void draw_platform()
{
  setcolor(7);
 gotoxy(platformX ,platformY);cout<<"       ";
 gotoxy(platformX ,platformY);cout<<"ÜÜÜÜÜÜ";
 setcolor(7);
 Sleep(5);
}
void simple_keyboard_input()
{
    if (kbhit())
      {
            KB_code = getch();
            //cout<<"KB_code = "<<KB_code<<"\n";
            switch (KB_code)
            {
                case KB_ESCAPE:
                    QuitGame=true;
                break;
                case KB_LEFT:
                           //Do something
                    platformX=platformX-4;if(platformX<3) platformX=3;
                break;
                case KB_RIGHT:
                           //Do something     
                    platformX=platformX+4;if(platformX>74) platformX=74;
                break;
                case KB_UP:
                           //Do something                     
                break;
                case KB_DOWN:
                           //Do something                     
                break;
            }        
      }
}
void setcolor(WORD color)
{
    SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE),color);
    return;
}
void gotoxy(int x, int y)
{
  static HANDLE hStdout = NULL;
  COORD coord;
  coord.X = x;
  coord.Y = y;
  if(!hStdout)
  {
    hStdout = GetStdHandle(STD_OUTPUT_HANDLE);
  }
  SetConsoleCursorPosition(hStdout,coord);
}
void clrscr(void)
{
  static HANDLE hStdout = NULL;      
  static CONSOLE_SCREEN_BUFFER_INFO csbi;
  const COORD startCoords = {0,0};   
  DWORD dummy;
  if(!hStdout)               
  {
    hStdout = GetStdHandle(STD_OUTPUT_HANDLE);
    GetConsoleScreenBufferInfo(hStdout,&csbi);
  }
  FillConsoleOutputCharacter(hStdout,
                             ' ',
                             csbi.dwSize.X * csbi.dwSize.Y,
                             startCoords,
                             &dummy);    
  gotoxy(0,0);
}
 
    
    - 8,490
- 3
- 24
- 28
