Как я могу определить, нажата ли какая-либо клавиша в C ++? - PullRequest
2 голосов
/ 18 марта 2020

Я ищу способ определить, нажата ли какая-либо клавиша в консольном приложении C ++ среды Windows. Акцент на любую, не конкретную c клавишу или набор ключей. Я искал по всему этому сайту, и я не могу найти ответ. Лучшее, что я нашел, - это использовать функцию GetKeyState или GetAsyncKeyState, но без примеров того, как ее использовать, и я также проверил документацию на веб-сайте Microsoft и до сих пор не уверен, как бы ее использовать.

Если это актуально и это помогает, я использую Visual Studio, и при создании этого проекта я выбрал Пустой проект, а не Консольное приложение.

Предполагается, что схема программы будет выглядеть следующим образом:

Clock flowchart

Вот код, который я использовал до сих пор в своей основной. cpp файл:

#ifndef MAINCPP
#define MAINCPP

#include "TwelveClock.h"
#include "TwentyFourClock.h"
#include <iostream>
#include <iomanip>
#include <Windows.h>
using namespace std;

void displayMenu() {
    cout << setw(27) << setfill('*') << "" << endl;
    cout << "* 1 -- Add One Hour" << setfill(' ') << setw(8) << '*' << endl;
    cout << "* 2 -- Add One Minute" << setw(6) << '*' << endl;
    cout << "* 3 -- Add One Second" << setw(6) << '*' << endl;
    cout << "* 4 -- Exit Program" << setw(8) << '*' << endl;
    cout << setw(27) << setfill('*') << "" << endl;
}

void displayClocks(TwentyFourClock& tfc, TwelveClock& tc) {
    cout << setfill('*') << setw(24) << "" << "    " << setw(25) << "" << endl;
    cout << setfill(' ') << "*" << setw(17) << "12-Hour Clock" << setw(6) << "*" << "    *" << setw(17) << "24-Hour Clock" << setw(7) << "*" << endl;

    cout << "*" << setw(5) << "" << setw(2) << setfill('0') << tc.Get_hour() << ":" << setw(2) << tc.Get_minute() << ":" << setw(2) << tc.Get_second() << " " << tc.Get_strPM_status() <<setfill(' ') << setw(7) << "*";
    cout << "    *" << setw(7) << "" << setw(2) << setfill('0') << tfc.Get_hour() << ":" << setw(2) << tfc.Get_minute() << ":" << setw(2) << tfc.Get_second() << setfill(' ') << setw(9) << "*" << endl;

    cout << setfill('*') << setw(24) << "" << "    " << setw(25) << "" << endl;
}

int main() {
    TwentyFourClock TwentyFour;
    TwelveClock Twelve;

    while (1) {

        system("cls"); 
        displayClocks(TwentyFour, Twelve);

        //FIXME: check if button is pressed 

        TwentyFour.Set_second(TwentyFour.Get_second() + 1);
        Twelve.Set_second(Twelve.Get_second() + 1);
        Sleep(1000);
    }

    return 0;
}

#endif

Также я Я обеспокоен тем, что моя программа не сможет даже обнаружить какой-либо ввод из-за того, что функция сна приостанавливает выполнение. Если это так, что будет лучшим подходом к этому? Я ценю всю помощь, которую я получаю.

1 Ответ

2 голосов
/ 19 марта 2020

_kbhit позволяет проверить, была ли нажата клавиша. В отличие от _getch , он возвращается немедленно и не блокируется, если во входном буфере нет данных для чтения.

Обе функции являются спецификациями Microsoft c для C Runtime (CRT), и не являются частью Standard C или C ++.


Ответы на второстепенные вопросы:

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

Консольный ввод обрабатывается ОС и буферизуется для вас, пока вы не прослушиваете ввод. Чтение потока из консоли ввода не должно быть активным в момент поступления ввода. Он всегда будет в состоянии наблюдать ввод из буфера, когда он проснется, чтобы проверить.

Если это так, какой будет лучший подход к этому?

Этого не произойдет. И все же, есть лучшие варианты для реализации требований. Поскольку в настоящее время это реализовано, приложение не сможет отвечать на входные данные до истечения времени ожидания Sleep. Несмотря на надежность, это приводит к заметной задержке между нажатием клавиши пользователем и реагированием на него приложения.

Существуют способы решения этой проблемы. Как API Windows, так и язык программирования C ++ предлагают сервисы, позволяющие реализовать операцию ожидания, которая возвращается, как только выполняется одно из нескольких условий (например, ожидание нажатия клавиши или истечения времени ожидания).

Решения задействованы и требуют глубокого знакомства с Windows API или C ++ - в идеале и тем, и другим - для усвоения. Я сомневаюсь, что вам было бы полезно (чтобы попытаться) выучить их на этом этапе. Продолжите свое путешествие и вернитесь к этому позже, наслаждаясь комфортом, зная, что это можно решить.

...