Key capture

Asked

Viewed 1,118 times

5

I’m developing a C-language cover game (gcc 4.9.2) to the Ubuntu terminal 15.04.

I need to capture a key typed by the user so that he can change the direction in which the topsail anda (wupward, s down, ato the left, d right).

For this, I am using the following code snippet, inside a loop that moves the cover automatically while the user does not change the direction:

if(kbhit())
    seta = getchar();

seta is a variable of the type char which stores the typed key.

The program does the reading correctly, however, it also writes on the screen the captured character, which obviously cannot happen in a game of this type.

Are there any C function that captures the key without writing the character on the screen or any equivalent procedure?

Obs.: Although kbhit() is originally a function of conio.h, managed to set it to Linux and is working perfectly.

3 answers

1

Implement this function by gdj:

#include <termios.h>  
#include <unistd.h>  
#include <errno.h>  
#define ECHOFLAGS (ECHO | ECHOE | ECHOK | ECHONL)  
int set_disp_mode(int fd,int option)  
{  
   int err;  
   struct termios term;  
   if(tcgetattr(fd,&term)==-1){  
     perror("Cannot get the attribution of the terminal");  
     return 1;  
   }  
   if(option)  
        term.c_lflag|=ECHOFLAGS;  
   else  
        term.c_lflag &=~ECHOFLAGS;  
   err=tcsetattr(fd,TCSAFLUSH,&term);  
   if(err==-1 && err==EINTR){  
        perror("Cannot set the attribution of the terminal");  
        return 1;  
   }  
   return 0;  
} 

And then when it’s time to call

while(1) {
    if (kbhit()) 
    {
        fflush(stdin);
        set_disp_mode(STDIN_FILENO,0); // 0 faz não exibir, se caso quiser voltar a exibir chame a função passando 1
        int c = getch();

        if (c == 65) // a
        { ...
  • @Joãopedro That would be http://stackoverflow.com/a/7469410/3257568 ?

  • @Joãopedro How you implemented kbhit?

  • I mean the code inside kbhit, you said you implemented, no?

  • @Joãopedro Take a look at this function set_disp_mode implements it and calls it with value 0 before the getchar()

  • @Joãopedro I updated my answer

  • you have some getchar before the while?

  • Quiet then, I’m glad you solved :)

  • If possible mark as the right answer, thank you!

Show 3 more comments

0

The getch() function captures the user without showing the answer on the screen. Take a look at the github link:

https://github.com/CarlosAdir/C-Programs/tree/master/Tutoriais

Download the entire folder and run the 8-extras file. c and see how it works. The kbhitgetch.pdf file explains and has a good basis for understanding how it works behind.

0

For Unix-based systems, you can use the functions of header termios.h and fcntl.h to implement the functions kbhit and getch windows.

According to these pages 1 2, this can be done as follows:

#include <stdio.h>
#include <termios.h>
#include <unistd.h>
#include <fcntl.h>

int kbhit(void)
{
  struct termios oldt, newt;
  int ch;
  int oldf;

  tcgetattr(STDIN_FILENO, &oldt);
  newt = oldt;
  newt.c_lflag &= ~(ICANON | ECHO);
  tcsetattr(STDIN_FILENO, TCSANOW, &newt);
  oldf = fcntl(STDIN_FILENO, F_GETFL, 0);
  fcntl(STDIN_FILENO, F_SETFL, oldf | O_NONBLOCK);

  ch = getchar();

  tcsetattr(STDIN_FILENO, TCSANOW, &oldt);
  fcntl(STDIN_FILENO, F_SETFL, oldf);

  if(ch != EOF)
  {
    ungetc(ch, stdin);
    return 1;
  }

  return 0;
}

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;
}

As an alternative, there is the library ncurses, that provides the function getch, yet I don’t know if there is support for the function kbhit. To use it, it is necessary to include curses.h, if not installed, open a terminal and type:

sudo apt-get update && sudo apt-get install ncurses-dev

Browser other questions tagged

You are not signed in. Login or sign up in order to post.