How to know if you pressed a key without ENTER in C++ with Linux?

Question:

My problem is that I can't know what key I pressed without pressing ENTER in C++ with Linux . I am aware of the GetAsyncKeyState() function, but it is only available on Windows with the <windows.h> library.

The only solutions I found were with <conio.h> s getch() but it's the same, it's only available on Windows .

What library or what function should I use to solve this?

It's a console program and I'm using C++14 with Linux Mint 18.3 , thanks in advance.

Answer:

The C++ libraries, by default, do not have the functionality you ask for.

The reason must be found in the operation of the terminal's input buffer. Control is not returned to the program until enter is pressed, then by traditional mechanisms it will be impossible.

I can't offer you my own solution because I don't have a linux operating system right now that I can afford to tinker with. I have compiled a couple of examples that, a priori, could work.

One possibility is to use the stty command to modify the behavior of the input. This command allows you to modify the behavior of the terminal input to suit your needs ( source ):

#include<stdio.h>

int main(void){
  int c;
  /* configuramos el terminal para que las pulsaciones se envien
     directamente a stdin */
  system ("/bin/stty raw");
  while((c=getchar())!= '.') {
    /* Tienes que encontrar un mecanismo de escape alternativo a CTRL-D,
       ya que éste no funciona en el modo 'raw' */
    putchar(c);
  }
  /* Se restaura el modo normal de trabajo de la terminal */
  system ("/bin/stty cooked");
  return 0;
}

Another possibility, a little more cumbersome, is to disable the ICANON flag (canonical mode) to allow the terminal to provide you with the characters as the user enters them. This method should be available in UNIX environments ( source ):

#include<stdio.h>
#include <termios.h>    //termios, TCSANOW, ECHO, ICANON
#include <unistd.h>     //STDIN_FILENO


int main(void){   
    int c;   
    static struct termios oldt, newt;

    /* tcgetattr obtiene la configuración actual del terminal
       STDIN_FILENO se utiliza para escribir la configuración en oldt */
    tcgetattr( STDIN_FILENO, &oldt);
    /* se hace una copia de la configuración */
    newt = oldt;

    /* se deshabilita el flag ICANON */
    newt.c_lflag &= ~(ICANON);          

    /* se envia la nueva configuración a STDIN
       usamos TCSANOW para modificar la configuración. */
    tcsetattr( STDIN_FILENO, TCSANOW, &newt);

    /* En este caso se usa la tecla 'e' para salir */
    while((c=getchar())!= 'e')      
        putchar(c);                 

    /* se restaura la configuración original */
    tcsetattr( STDIN_FILENO, TCSANOW, &oldt);

    return 0;
}
Scroll to Top