Почему _getch() все еще ждет ввода вместо того, чтобы напрямую регистрировать пользовательский ввод?

Я хотел бы использовать пользовательский ввод со стрелками, чтобы пользователю не приходилось нажимать ввод каждый раз после нажатия стрелки. Поэтому я решил использовать _getch(), который якобы делает именно это. Это часть библиотеки conio.h, которую я импортировал. Однако в моем случае _getch() также требует, чтобы пользователь нажал клавишу ввода, и не сразу регистрирует пользовательский ввод, как следовало бы. Как я могу это исправить? (Я работаю на окнах)

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

using namespace std;

int main() {
    int p = _getch();
    cout<<p;
    return 0;
}

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


person HeroCODE    schedule 18.01.2021    source источник
comment
В старые дни DOS я думаю, что каждое нажатие клавиши со стрелкой приводило к двум символам, по какой-то причине я не могу вспомнить. У вас возникает та же проблема, если вместо этого вы используете, например, клавиши W, A, S, D?   -  person Lundin    schedule 18.01.2021
comment
К сожалению, у меня такая же проблема с любым другим ключом.   -  person HeroCODE    schedule 18.01.2021
comment
пройдите свой код с помощью отладчика! симптомы, которые вы описываете, просто не могут произойти с кодом, который вы дали.   -  person engf-010    schedule 18.01.2021
comment
Нет, _getch() не линейно-ориентированный, но вывод может быть. В C я бы проверил это с помощью printf("%d\n", p);, возможно, также сбросить вывод. И, как говорит @Lundin, навигационные и функциональные клавиши возвращают два значения: если задано escape-значение, вы возвращаетесь к другому.   -  person Weather Vane    schedule 18.01.2021
comment
@ engf-010 Я не могу объяснить, почему программа должна ждать. Я упустил из виду, что это не петля. Суть _getch() в том, что в отличие от getchar() он не линейный (и исходит от клавиатуры, а не STDIN).   -  person Weather Vane    schedule 18.01.2021
comment
@Weather Vane: Возможно (вероятно) сообщение консоли отладки ожидает подтверждения.   -  person engf-010    schedule 18.01.2021
comment
Я просто редактировал эту мысль... но ты сделал это. Если OP хочет получить последовательность клавиш для навигационных и функциональных клавиш, она должна быть в цикле.   -  person Weather Vane    schedule 18.01.2021


Ответы (1)


Из Microsoft Docs< /а>:

При чтении функциональной клавиши или клавиши со стрелкой каждая функция должна вызываться дважды; первый вызов возвращает 0 или 0xE0, а второй вызов возвращает фактический код клавиши.

Таким образом, исправленная версия вашего кода может выглядеть так:

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

int main() {
    int p = 0;
    while(p == 0 || p == 0xE0)
        p = _getch();

    std::cout << p;

    return 0;
}
person Inigo Selwood    schedule 18.01.2021
comment
это не отвечает на вопрос ОП, и указанный код просто неверен! - person engf-010; 24.01.2021
comment
Привет, engf-010, не хочешь объяснить, почему? - person Inigo Selwood; 25.01.2021
comment
пример вашего кода: прочитайте цитируемый вами MSDN и рассмотрите свой код (нужно ли говорить больше). Что касается отсутствия ответа на вопрос ОП, он думает, что его код неверен (что так и есть), но симптомы, которые он описывает, НЕ исходят из этого. Вероятно, это сообщение DEBUG-Console, запрашивающее Enter. - person engf-010; 26.01.2021
comment
Что касается вашего кода, подсказка: что, если _getch() возвращает 0xE0? почему цикл, когда если будет достаточно и лучше отражает намерение (в то время как предполагает, что может произойти несколько _getch() == 0)? - person engf-010; 26.01.2021
comment
Спасибо за разъяснение по поводу 0xE0. Я бы сказал, что цикл while будет выводить ту же сборку, что и оператор if, но при этом будет таким же ясным и более лаконичным. - person Inigo Selwood; 26.01.2021
comment
Сборка ? Когда я читаю чужой код, я не читаю вывод сборки. ваш код сбивает с толку. авто ch = _getch(); ch = (ch == 0 или ch == 0xE0) ? _getch() : канал; не о чем спорить, нет? - person engf-010; 26.01.2021