Консоль. Считывание нажатой клавиши

Рейтинг: 3Ответов: 2Опубликовано: 12.04.2015

Нужно, чтобы после нажатия на кнопку программа работала дальше. Чтобы после этой кнопки не приходилось еще жать Enter. Как я понял, этим занимается getchar(), но у меня он не работает, приходится жать Enter. Код для Windows:

while (z != ' ') {
    cout<< "Нажмите SPACE " << endl;
    z = getchar();
}

Ответы

▲ 3

На Windows можно использовать getch() вместе с заголовочным файлом conio.h.

#include <iostream>
#include <conio.h>


int main() {
   int z
   while (z != ' ') {
      cout<< "Нажмите SPACE " << endl;
      z = getch();
   }
}

На *nix-OS есть curses.h (ncurses.h), там также имеется функция getch(). Однако при использовании данной функции вы остаетесь привязаны к curses, поэтому желательно использовать следующую конструкцию:

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

int getch( ) {
   struct termios oldt,
   newt;
   int ch;
   tcgetattr( STDIN_FILENO, &oldt );
   newt = oldt;
   newt.c_lflag &= ~( ICANON | ECHO );
   tcsetattr( STDIN_FILENO, TCSANOW, &newt );
   ch = getchar();
   tcsetattr( STDIN_FILENO, TCSANOW, &oldt );
   return ch;
}

Также на Windows можно использовать PDCurses для создания мультиплатформенных консольных приложений, он почти полностью совместим с ncurses.

▲ 2

Переносимым образом — никак.

C++ рассчитан на то, что стандартные потоки могут быть перенаправлены, поэтому ввод буферизуется, и доступа напрямую к клавиатуре нет.

Тем не менее, есть способы, основанные на системно-зависимых библиотеках.

Например, под Windows-системами вы можете воспользоваться WinAPI-функциями ReadConsoleInput/GetNumberOfConsoleInputEvents.

Под Linux-системами вам поможет библиотека curses/ncurses.

На старых DOS-системах есть getch в conio.h.

Учтите, что если вы пользуетесь низкоуровневым вводом/выводом, нормальный потоковый ввод-вывод скорее всего не будет функционировать нормально. Так что или cin/cout, или низкоуровневые трюки, иначе сюрпризов не избежать.