Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Continuous keyboard input in C

Tags:

c++

c

console

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!

like image 913
Zain Zafar Avatar asked Nov 09 '13 10:11

Zain Zafar


People also ask

Which statement can be used to get keyboard input in C?

Keyboard Input: scanf()

What is Getch in C programming?

What is getch() in C? The getch() is a predefined non-standard function that is defined in conio. h header file. It is mostly used by the Dev C/C++, MS- DOS's compilers like Turbo C to hold the screen until the user passes a single value to exit from the console screen.

Why does scanf doesn't wait for input?

If we enter the values separated by space, the function returns when space is encountered but the values after space remains in the input buffer. That's why the second scanf() function will not wait for user input, instead it takes the input from the buffer.


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.

like image 163
Alexandru Barbarosie Avatar answered Oct 12 '22 07:10

Alexandru Barbarosie


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;
}
like image 29
Rahul Tripathi Avatar answered Oct 12 '22 07:10

Rahul Tripathi


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.

The Matrix  falling numbers

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);
}
like image 43
Software_Designer Avatar answered Oct 12 '22 07:10

Software_Designer