Моя проблема в следующем:

Я хочу сделать программу, простой текстовый редактор, который может работать со всеми клавишами набора клавиатур, такими как функциональные клавиши (от F1 до F12), Command, Left-Shift, ALT или TAB.

Точнее, я хочу иметь возможность назначать все клавиши для конкретных операций.

Я сделал программу для распечатки значений ASCII этих ключей, но ключи не принимаются так, как я хочу, моя тестовая программа распечатывает либо значения нескольких кодов ASCII, либо не принимает их все, как при нажатии кнопки Командная клавиша вместо этого:

Моя тестовая программа для вывода ASCII-значения нажатой клавиши:

#include <stdio.h> 

int main (void)
{
    char k;

    printf("\n\n\n\n");

    while(1)
    {

       printf("Please press any key:");

       k = getchar();
       getchar();

       printf("ASCII code of given input key: %d",k);
       printf("\n\n\n");
    }
}

Вывод после нажатия клавиши F2:

Please press any key:^[OQ
ASCII code of given input key: 27


Please press any key:ASCII code of given input key: 81

Вывод после нажатия клавиши F2:

Please press any key:^[[15~
ASCII code of given input key: 27


Please press any key:ASCII code of given input key: 49


Please press any key:ASCII code of given input key: 126

Вывод после нажатия Command-, Alt- или Left-Shift-Key:

Please press any key:               // no reaction at all

Из-за того, что я думаю, что это должно быть сделано легко, потому что, конечно, нормально использовать все клавиши клавиатуры в программе, мне, как новичку, не так просто найти правильный способ добиться этого. .

Я нашел этот вопрос здесь, в Stackoverflow, но он относится к С#: Специальные клавиши на клавиатуре

Почему я не могу получить значение ASCII этих ключей?

Извините, если у меня может сложиться ошибочное впечатление, что эти ключи принадлежат значениям ASCII.

0
RobertS supports Monica Cellio 27 Окт 2019 в 18:37
1
"Почему я не могу получить значение ASCII для этих ключей?" -- потому что у этих ключей нет связанного значения ASCII. То, что вы получаете при нажатии F2, - это два байта данных, которые не имеют ничего общего с ASCII и просто случайно считываются вашей программой, потому что терминал передает их ей. Остальные клавиши просто игнорируются и не передаются программе из терминала. Если вы хотите зафиксировать каждое возможное нажатие клавиши, вам нужно будет читать терминал в необработанном режиме.
 – 
Marco Bonelli
27 Окт 2019 в 18:42
1
«Как вы используете эти ключи в своей программе?» Я полагаюсь на то, что операционная система (или инструментарий, такой как Qt или SFML) расшифрует их за меня. Попытка просто прочитать необработанные коды клавиатуры без драйвера ОС или набора инструментов была бы серьезной тратой моего времени.
 – 
Jesper Juhl
27 Окт 2019 в 19:10
2
Ответ заключается в том, что это зависит от платформы, и даже на одной платформе может зависеть от типа приложения — приложение с графическим интерфейсом будет получать сообщения с клавиатуры, в то время как консольная программа Windows может вызывать функцию, которая возвращает сканирование. -коды, а терминальная программа Linux может получать escape-последовательности или, возможно, скан-коды в зависимости от того, какой уровень и через какое устройство вы можете выбрать для доступа к клавиатуре. Таким образом, ваш вопрос требует некоторого контекста относительно платформы. С помощью кроссплатформенной библиотеки можно использовать общий код на разных платформах, но тогда вам нужно выбрать свою библиотеку.
 – 
Clifford
27 Окт 2019 в 19:36
2
Возможно, ваше поисковое фу нуждается в оттачивании? Например: stackoverflow.com/ вопросы/24708700/…. Обратите внимание, что коды специальных клавиш не являются кодами ASCII. ASCII — это кодировка символов (с ограниченным набором управляющих кодов), а не клавиатурная кодировка. «CURSOR-LEFT» не является символом (и не имеет определенного управляющего кода).
 – 
Clifford
27 Окт 2019 в 20:10

1 ответ

Доступ к «специальным клавишам» не является частью стандартной библиотеки, потому что язык не предполагает какого-либо конкретного оборудования ввода-вывода, такого как экран и клавиатура, он предполагает только стандартные потоки ввода-вывода на основе символов, и данные в этих потоках относятся к символам, а не к клавишам.

Таким образом, получение событий клавиатуры и скан-кодов и конкретных платформ. Однако существуют кроссплатформенные средства, с помощью которых вы можете получить некоторую общность между системами, поддерживающими клавиатуру (например, настольные компьютеры - не все, на чем работает C, является настольным компьютером).

Например, для текстовых консольных приложений, таких как в вашем примере, вы можете использовать библиотеку ncurses, которая является клоном библиотеки unix curses и имеет почти эквивалент Windows в библиотеке PDcurses.

Например, в этих вариантах curses вы можете написать:

int ch = getch() ;
if(ch == KEY_LEFT)
    printw("Left arrow is pressed\n");

Под капотом это оболочка для специфичных для платформы средств. Если кроссплатформенность не является проблемой, вы можете использовать эти средства напрямую. Например, в MSVC++ есть библиотека conio, которая имеет _getch() аналогична приведенной выше, за исключением того, что для несимвольных ключей она возвращает 0x00 или 0xE0 и возвращает код клавиши при повторном вызове.

Для приложений с графическим интерфейсом цикл сообщений приложений будет получать события клавиатуры, точные средства будут различаться в зависимости от системы, но опять же существуют кросс-платформенные решения, такие как, например, Qt или WxWidgets.

1
Clifford 27 Окт 2019 в 21:10
Да, я думал о ncurses-библиотеке, кроме того, чтобы получить экран за пределами самого терминала. Но что касается приведенного вами примера. Как мне добиться, чтобы макрос KEY_LEFT соответствовал выводу клавиши левого курсора?
 – 
RobertS supports Monica Cellio
27 Окт 2019 в 20:22