it-swarm.com.de

C++ Erkennen, wenn der Benutzer die Pfeiltaste drückt

Ich habe ein Problem mit dem Erkennen von Pfeiltasten in meiner C++ - Konsolenanwendung. Ich habe alles versucht, was ich hier und auf anderen Tutorialseiten gefunden habe, aber alle geben mir dasselbe, wenn ich auf den Pfeil drücke: 

Process returned 0 <0x0> execution time : 2.249 s
Press any key to continue.

Hier sind alle Methoden zum Erkennen des Tastendrucks, die ich ausprobiert habe, alle auf dieselbe Weise. Dies sind die einzigen zwei in meinem Code, die anderen, die ich versuchte, zu löschen, anstatt sie zu kommentieren. 

Methode eins:

c1 = getch();
if(c1 == 0)
{

    c2 = getch();

    if(c2 == 72) {cout << endl << "Up Arrow" << endl;}
    else if(c2 == 80) {cout << endl << "Down Arrow" << endl;}
    else{cout << endl << "Incorrect Input" << endl;}

}

Methode zwei:

switch(getch()) {
case 65:
       cout << endl << "Up" << endl;//key up
    break;
case 66:
    cout << endl << "Down" << endl;   // key down
    break;
case 67:
    cout << endl << "Right" << endl;  // key right
    break;
case 68:
    cout << endl << "Left" << endl;  // key left
    break;
}

Gibt es einen Fehler in meinem Code, durch den ich zu meiner Hauptmethode zurückkehrte, oder hat er Code übersprungen? Gibt es einen schnelleren Weg, dies zu tun? Ich bin fast zu 100% sicher, dass mein anderer Code nichts mit diesem Problem zu tun hat, weil ich den Code von anderen Aspekten des Programms abhängig gemacht habe und das gleiche Problem hatte. 

Wieder habe ich jede Methode ausprobiert, bei der ich die Pfeiltaste drücken konnte, und ich bekomme das gleiche Problem. Wenn es wichtig ist, bin ich auf einem Windows 8 Samsung ATIV Smart PC und benutze das Tastaturdock.

Vielen Dank im Voraus für jede Hilfe. 

#include <conio.h>
#include <iostream>
using namespace std;

#define KEY_UP 72
#define KEY_DOWN 80
#define KEY_LEFT 75
#define KEY_RIGHT 77

int main()
{
    int c = 0;
    while(1)
    {
        c = 0;

        switch((c=getch())) {
        case KEY_UP:
            cout << endl << "Up" << endl;//key up
            break;
        case KEY_DOWN:
            cout << endl << "Down" << endl;   // key down
            break;
        case KEY_LEFT:
            cout << endl << "Left" << endl;  // key left
            break;
        case KEY_RIGHT:
            cout << endl << "Right" << endl;  // key right
            break;
        default:
            cout << endl << "null" << endl;  // not arrow
            break;
        }

    }

    return 0;
}

ausgabe wie folgt:

Up

Down

Right

Left

Up

Left

Right

Right

Up

pfeiltaste erkannt!

13
arbboter

Hier ist ein alternativer Weg ohne getch () using events (gut kommentiert und ich habe versucht, es so einfach wie möglich zu machen)

#include <iostream>
#include <Windows.h>

int main(int argc, char *argv[]){

    HANDLE rhnd = GetStdHandle(STD_INPUT_HANDLE);  // handle to read console

    DWORD Events = 0;     // Event count
    DWORD EventsRead = 0; // Events read from console

    bool Running = true;

    //programs main loop
    while(Running) {

        // gets the systems current "event" count
        GetNumberOfConsoleInputEvents(rhnd, &Events);

        if(Events != 0){ // if something happened we will handle the events we want

            // create event buffer the size of how many Events
            INPUT_RECORD eventBuffer[Events];

            // fills the event buffer with the events and saves count in EventsRead
            ReadConsoleInput(rhnd, eventBuffer, Events, &EventsRead);

            // loop through the event buffer using the saved count
            for(DWORD i = 0; i < EventsRead; ++i){

                // check if event[i] is a key event && if so is a press not a release
                if(eventBuffer[i].EventType == KEY_EVENT && eventBuffer[i].Event.KeyEvent.bKeyDown){

                    // check if the key press was an arrow key
                    switch(eventBuffer[i].Event.KeyEvent.wVirtualKeyCode){
                        case VK_LEFT:
                        case VK_RIGHT:
                        case VK_UP:
                        case VK_DOWN:   // if any arrow key was pressed break here
                            std::cout<< "arrow key pressed.\n";
                            break;

                        case VK_ESCAPE: // if escape key was pressed end program loop
                            std::cout<< "escape key pressed.\n";
                            Running = false;
                            break;

                        default:        // no handled cases where pressed 
                            std::cout<< "key not handled pressed.\n";
                            break;
                    }
                }

            } // end EventsRead loop

        }

    } // end program loop

    return 0;
}

(Dank eines Kommentators weiß ich jetzt, dass dieser Code kein Standard ist, obwohl er funktioniert, wenn Sie mit g++ kompilieren, weitere Informationen in den Kommentaren.)

5
James
// Example for inputting a single keystroke in C++ on Linux
// by Adam Pierce <[email protected]> on http://www.doctort.org/adam/nerd-notes/reading-single-keystroke-on-linux.html
// This code is freeware. You are free to copy and modify it any way you like.
// Modify by me Putra Kusaeri


#include <iostream>
#include <termios.h>
#define STDIN_FILENO 0
using namespace std;
int main()
{
// Black magic to prevent Linux from buffering keystrokes.
    struct termios t;
    tcgetattr(STDIN_FILENO, &t);
    t.c_lflag &= ~ICANON;
    tcsetattr(STDIN_FILENO, TCSANOW, &t);

// Once the buffering is turned off, the rest is simple.
    cout << "Enter a character: ";
    char c,d,e;
    cin >> c;
    cin >> d;
    cin >> e;
    cout << "\nYour character was ";
// Using 3 char type, Cause up down right left consist with 3 character
    if ((c==27)&&(d=91)) {
        if (e==65) { cout << "UP";}
        if (e==66) { cout << "DOWN";}
        if (e==67) { cout << "RIGHT";}
        if (e==68) { cout << "LEFT";}
    }
    return 0;
}
1
Putra Kusaeri

Prüfen Sie http://msdn.Microsoft.com/de-de/library/windows/desktop/ms684961(v=vs.85).aspx und http://msdn.Microsoft.com/en- us/library/windows/desktop/dd375731 (v = vs.85) .aspx

#include<windows.h>
#include <stdio.h>

int main()
{
    HANDLE hInput = GetStdHandle(STD_INPUT_HANDLE);
    DWORD NumInputs = 0;
    DWORD InputsRead = 0;
    bool running = true;

    INPUT_RECORD irInput;

    GetNumberOfConsoleInputEvents(hInput, &NumInputs);

    ReadConsoleInput(hInput, &irInput, 1, &InputsRead);

    switch(irInput.Event.KeyEvent.wVirtualKeyCode)
    {
        case VK_ESCAPE:
        puts("Escape");
        break;

        case VK_LEFT:
        puts("Left");
        break;

        case VK_UP:
        puts("Up");
        break;

        case VK_RIGHT:
        puts("Right");
        break;

        case VK_DOWN:
        puts("Down");
        break;
    } 

}
1
user93353

Einige der hier gegebenen Antworten berücksichtigen nicht die Tatsache, dass beim Drücken einer Pfeiltaste 2 Zeichen empfangen werden. Zusätzlich ist zu beachten, dass das eingegebene Zeichen vorzeichenloses Zeichen sein sollte. Um festzustellen, ob eine Pfeiltaste gedrückt wurde, verwenden wir ASCII Wert 224, der nur in einem 8-Bit-Zeichen (vorzeichenloses Zeichen) und nicht in dem 7-Bit-Zeichen mit Vorzeichen gespeichert werden kann .

Sie können das folgende Code-Snippet verwenden. Hier werden 2 Arten von Eingaben verarbeitet. ch1 ist das erste Zeichen, das der Benutzer eingibt. Dies ist die Eingabe, die der Benutzer eingibt. Bei Pfeiltasten wird jedoch eine Folge von 2 Zeichen ch1 und ch2 empfangen. ch1 gibt an, dass eine Pfeiltaste gedrückt wurde, ch2 gibt an, welche Pfeiltaste gedrückt wurde.

const int KEY_ARROW_CHAR1 = 224;
const int KEY_ARROW_UP = 72;
const int KEY_ARROW_DOWN = 80;
const int KEY_ARROW_LEFT = 75;
const int KEY_ARROW_RIGHT = 77;

unsigned char ch1 = _getch();
if (ch1 == KEY_ARROW_CHAR1)
{
    // Some Arrow key was pressed, determine which?
    unsigned char ch2 = _getch();
    switch (ch2) 
    {
    case KEY_ARROW_UP:
        // code for arrow up
        cout << "KEY_ARROW_UP" << endl;
        break;
    case KEY_ARROW_DOWN:
        // code for arrow down
        cout << "KEY_ARROW_DOWN" << endl;
        break;
    case KEY_ARROW_LEFT:
        // code for arrow right
        cout << "KEY_ARROW_LEFT" << endl;
        break;
    case KEY_ARROW_RIGHT:
        // code for arrow left
        cout << "KEY_ARROW_RIGHT" << endl;
        break;
    }
}
else
{
    switch (ch1)
    {
        // Process other key presses if required.
    }
}
0
Saket Sharad

Die vorherige Antwort von arbboter ist nahe, vernachlässigt jedoch die Tatsache, dass die Pfeiltasten (und andere Sondertasten) einen Scan-Code von zwei Zeichen zurückgeben. Der erste ist entweder (0) oder (224) und gibt an, dass der Schlüssel ein erweiterter ist. Der zweite enthält den Scan-Code-Wert.

Ohne dies zu berücksichtigen, werden die ASCII - Werte für "H", "K", "M" und "P" als "Up", "Down", "Left" und "Right" falsch interpretiert.

Hier ist eine modifizierte Version des Arbboter-Codes, um das Lesen des erweiterten Werts zu demonstrieren, wenn eine der Pfeiltasten gedrückt wird:

#include <conio.h>
#include <iostream>
using namespace std;

#define KEY_UP    72
#define KEY_LEFT  75
#define KEY_RIGHT 77
#define KEY_DOWN  80

int main()
{
    int c, ex;

    while(1)
    {
        c = getch();

        if (c && c != 224)
        {
            cout << endl << "Not arrow: " << (char) c << endl;
        }
        else
        {
            switch(ex = getch())
            {
                case KEY_UP     /* H */:
                    cout << endl << "Up" << endl;//key up
                    break;
                case KEY_DOWN   /* K */:
                    cout << endl << "Down" << endl;   // key down
                    break;
                case KEY_LEFT   /* M */:
                    cout << endl << "Left" << endl;  // key left
                    break;
                case KEY_RIGHT: /* P */
                    cout << endl << "Right" << endl;  // key right
                    break;
                default:
                    cout << endl << (char) ex << endl;  // not arrow
                    break;
            }
        }
    }

    return 0;
}
0
Erik Anderson