Friday, December 10, 2010

getch() & getche() in gcc/g++


As sometimes, we use the header "conio.h" in windows (although deprecated), we feel the need for it sometimes in linux as well, and unfortunately, in linux, i.e. in gcc/g++, there is nothing built in like "conio.h", to be more precise, getch() and getche() functions. getch() reads directly from console, without any buffering, and so does getche(). The difference between them is, getch() doesn't echo the pressed key on the screen while getche() does.

Well, it's not very hard to write your own getch() and getche() routines in linux if you know some system programming, and console attributes used in linux. All you need to do, is to stop stdin buffering before reading the character, and then restore the old settings again. Here goes the simple "conio.h" for gcc/g++:

/*
AUTHOR: zobayer
INSTRUCTION:
just make this file a header like "conio.h"
and use the getch() and getche() functions.
*/
#include <termios.h>
#include <unistd.h>
#include <stdio.h>

/* reads from keypress, doesn't echo */
int getch(void) {
    struct termios oldattr, newattr;
    int ch;
    tcgetattr( STDIN_FILENO, &oldattr );
    newattr = oldattr;
    newattr.c_lflag &= ~( ICANON | ECHO );
    tcsetattr( STDIN_FILENO, TCSANOW, &newattr );
    ch = getchar();
    tcsetattr( STDIN_FILENO, TCSANOW, &oldattr );
    return ch;
}

/* reads from keypress, and echoes */
int getche(void) {
    struct termios oldattr, newattr;
    int ch;
    tcgetattr( STDIN_FILENO, &oldattr );
    newattr = oldattr;
    newattr.c_lflag &= ~( ICANON );
    tcsetattr( STDIN_FILENO, TCSANOW, &newattr );
    ch = getchar();
    tcsetattr( STDIN_FILENO, TCSANOW, &oldattr );
    return ch;
}

Hope this helps. Please let me know if any error is found.

[Update:] However there is a library in gcc for some other similar functions of "conio.h", which is known as NCURSES library. Thanks to Muhammad Ridowan for letting me know this.


9 comments:

  1. Thanks, great help for me. Here some other stuff to emulate "conio.h"

    void gotoxy (int x, int y)
    {
    printf("%c[%d;%df", 0x1b, y, x);
    }

    void clrscr (void)
    {
    system("clear");
    }

    May it be helpful for someone other.
    Peter (DF5EQ)

    ReplyDelete
    Replies
    1. thanks bro it work perfectly............................

      Delete
  2. Awesome, thank you!!
    My Unbuntu 13.10 doesn't have NCURSES, but your code worked a charm.

    ReplyDelete
  3. Your code worked fine. Thank you!

    ReplyDelete
  4. It's still helpful. Thank you verrry much!

    ReplyDelete