C++コンソールアプリケーションで矢印キーの押下を検出する際に問題が発生しました。ここと他のチュートリアルサイトの両方で見つけたものをすべて試しましたが、矢印を押すたびに同じことが起こります。
Process returned 0 <0x0> execution time : 2.249 s
Press any key to continue.
ここに、私が試したキープレスを検出するすべての方法を示しますが、すべて同じ方法になります。これらは私のコードに残っている唯一の2つで、コメントアウトする代わりに削除しようとした他の2つです。
方法1:
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;}
}
方法2:
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;
}
コードにエラーがあり、メインメソッドに戻るのですか、それともコードをスキップしましたか?これを行うより速い方法はありますか?私は他のコードがこの問題とは何の関係もないことをほぼ100%確信しています。コードをプログラムの他の側面に依存しないように隔離し、同じ問題を抱え続けたからです。
繰り返しますが、私は見つけることができる矢印キーを押す方法をすべて試しましたが、私は同じ問題を抱え続けています。問題があれば、Windows 8 Samsung ATIV Smart PCでキーボードドックを使用しています。
助けてくれてありがとう。
#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;
}
このような出力:
Up
Down
Right
Left
Up
Left
Right
Right
Up
矢印キーの押下を検出しました!
getch()eventsを使用せずにそれを行う別の方法があります
#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;
}
(コメンターのおかげで、このコードは標準ではないことがわかりましたが、g++
、コメントの詳細)
// 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;
}
http://msdn.Microsoft.com/en-us/library/windows/desktop/ms684961(v = vs.85).aspx および 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;
}
}
前のarbboterの答えは近いですが、矢印キー(および他の特別なキー)が2文字のスキャンコードを返すという事実を無視しています。最初は(0)または(224)で、キーが拡張キーであることを示します。 2番目にはスキャンコード値が含まれます。
これを考慮しないと、ASCII "H"、 "K"、 "M"、および "P"の値は、 "Up"、 "Down"、 "Left"、および"正しい"。
矢印キーの1つが押されたときに拡張値を読み取ることを示すために、arbboterのコードを修正したバージョンを次に示します。
#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;
}
ここで与えられた回答のいくつかは、矢印キーを押すと2文字が受け取られるという事実を考慮していません。また、入力文字はnsigned charである必要があることに注意してください。これは、矢印キーが押されたかどうかを判断するために、ASCII value 224を使用します。 。
以下のコードスニペットを使用できます。ここでは2種類の入力が処理されます。 ch1は、ユーザーが入力する最初の文字です。これは、ユーザーがフィードしている入力です。ただし、矢印キーの場合、2文字のシーケンスがch1およびch2で受信されます。 ch1は矢印キーが押されたことを識別し、ch2は押された特定の矢印キーを決定します。
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.
}
}