Считывание нажатия стрелок С++ Linux Ubuntu

286
30 января 2019, 20:40

Пишу консольную игру 2048 и столкнулся с проблемой отсутствия стандартных функций С++ считывания нажатий на стелки на клавиатуре. getch() не работает, ибо не поддерживается. Подскажите пожалуйста, какие есть варианты? (в будущем будет использоваться как часть свич-кейса)

Answer 1

Нужно в консоли отключать автоматическое эхо и всю дребедень. Потом вернуть всё назад.

#include <termios.h>
#include <unistd.h>
#include <stdio.h>
#include <iso646.h>
int main(){
  int fd = STDIN_FILENO ;
  FILE* fp = stdin ;
  FILE* fo = stdout ;
  struct termios termios_p ;
  struct termios termios_pold ;
  if( tcgetattr(fd, &termios_p)) return 1;
  termios_pold = termios_p ;
  //cfmakeraw(&termios_p);
  termios_p.c_iflag &= ~(IGNBRK | BRKINT | PARMRK | ISTRIP
                           | INLCR | IGNCR | ICRNL | IXON);
  termios_p.c_oflag &= ~OPOST;
  termios_p.c_lflag &= ~(ECHO | ECHONL | ICANON | ISIG | IEXTEN);
  termios_p.c_cflag &= ~(CSIZE | PARENB);
  termios_p.c_cflag |= CS8;
  if( tcsetattr(fd, TCSANOW,&termios_p)) return 2;
  for(int i = 100;i>0;--i){
    int c = fgetc(fp);
    if(fprintf(stdout,"c=%c(%d)\n\r",c,c)<0) return 2;}
  if( tcsetattr(fd, TCSANOW,&termios_pold)) return 3;
  return 0;}
Answer 2

Для POSIX систем стандартной библиотекой для работы с терминалом является curses, и в частности её GNU'тая реализация ncurses. Вот небольшой Hello world, как получать ввод с помощью стрелок:

#include <ncurses.h>
int main() {
    unsigned x=0, y=0;
    int ch;
    initscr ();
    keypad (stdscr, 1);
    do {
        mvprintw(y, x, "Hello World !!!");
        refresh();
        ch = getch();
        mvprintw(y, x, "               ");
        switch (ch) {
            case KEY_UP   :  y--; y %= LINES; break;
            case KEY_DOWN :  y++; y %= LINES; break;
            case KEY_LEFT :  x--; x %= COLS ; break;
            case KEY_RIGHT:  x++; x %= COLS ; break;
        }
    } while (ch != 'q');
    endwin();
    return 0;
}

Компилировать с помощью gcc -lncurses move.c -o move. Само собой, библиотека (n)curses и хедеры должны быть установлены (обычно это пакеты ncurses и ncurses-dev). Выход по q.

Из ключевых моментов — вызов keypad (), который переводит библиотеку в режим интерпретации ввода функциональных клавиш «по одной за раз».

Предлагаемое дальнейшее чтение Ncurses Programming HOWTO

Answer 3
#include <termios.h>
#include <unistd.h>
#include <stdio.h>
int getch()
{
    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;
}

Имхо, самый простой вариант - это свой гетч без мам пап и установки ncurses.

READ ALSO
компиляторы для qt(и их настройка),windows sdk?,и c++

компиляторы для qt(и их настройка),windows sdk?,и c++

Всего лишь скачать,и посмотреть документацию? Ничоси легко!

261
Сигналы слоты qt

Сигналы слоты qt

Задача состоит в том, что есть два классаВ экземпляре одного из принимаются на вход данные (например чтение из файла) и после обработки передается...

253
Одинаковые байты, разные представления

Одинаковые байты, разные представления

Могут ли существовать две строки std::string a и std::string b, для которых a == b возвращает true, но они имеют разный вид при std::cout << a << b?

270
Можете объяснить смысл задачи?

Можете объяснить смысл задачи?

Ильнар в одной из комнат увидел странного роботаВо время выполнения алгоритма, он доставал из мешка разные камушки

241