我在C ++控制台应用程序中检测箭头键按下时遇到问题。我已经尝试了我在这里和其他教程网站上找到的所有内容,但每当我按下箭头时,所有这些都给了我同样的东西:
Process returned 0 <0x0> execution time : 2.249 s
Press any key to continue.
以下是检测我所尝试的按键的所有方法,所有方法都以相同的方式结束。这些是我的代码中剩下的两个,其他我尝试删除而不是注释掉。
方法一:
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;}
}
方法二:
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;
}
我的代码中是否有一些错误让我回到我的main方法,或者是否跳过了一些代码?有更快的方法吗?我几乎100%确定我的其他代码与此问题没有任何关系,因为我隔离了代码,使其依赖于程序的任何其他方面,并且我一直遇到同样的问题。
再一次,我尝试了各种方法来获得我能找到的箭头按键,并且我一直遇到同样的问题。如果重要的是,我使用的是Windows 8 Samsung ATIV Smart PC并使用键盘底座。
提前感谢您的帮助。
答案 0 :(得分:13)
#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
检测到箭头键按下了!
答案 1 :(得分:5)
这是另一种方法,在没有 getch()的情况下使用事件(评论很好,我试着尽可能简单)
#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++
编译它会有效,评论中会有更多信息)
答案 2 :(得分:1)
检查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;
}
}
答案 3 :(得分:1)
// Example for inputting a single keystroke in C++ on Linux
// by Adam Pierce <adam@doctort.org> 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;
}
答案 4 :(得分:1)
arbboter的上一个答案很接近,但是忽略了箭头键(和其他特殊键)返回两个字符的扫描代码的事实。第一个是(0)或(224),表示密钥是扩展密钥;第二个包含扫描代码值。
如果不考虑这一点,则“ H”,“ K”,“ M”和“ P”的ASCII值会被误解为“上”,“下”,“左”和“右”。 >
这是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;
}
答案 5 :(得分:0)
此处给出的某些答案并未考虑到按下箭头键会收到2个字符的事实。此外,应注意,输入字符应为 unsigned char 。这是因为要确定是否按下了箭头键,我们使用了ASCII值224,该值只能存储为8位字符(无符号字符),而不能存储为7位有符号字符。
您可以使用以下代码段。此处处理2种类型的输入。 ch1是用户输入的第一个字符。这是用户正在输入的输入。但是,在使用箭头键的情况下,会分别接收到两个字符ch1和ch2。 ch1标识已按下某个箭头键,ch2确定所按下的特定箭头键。
.stop{
-webkit-animation-iteration-count: 1;
-moz-animation-iteration-count: 1;
-ms-animation-iteration-count: 1;
-o-animation-iteration-count: 1;
animation-iteration-count: 1;
}
答案 6 :(得分:0)
=
这与上面的一些例子非常相似,只是我使用了
#include <iostream>
#include <conio.h>
const int KB_UP = 72;
const int KB_DOWN = 80;
const int KB_RIGHT = 77;
const int KB_LEFT = 75;
const int ESC = 27;
int main() {
while (true) {
int ch = _getch();
if (ch == 224) {
ch = _getch();
switch (ch) {
case KB_UP:
std::cout << "up\n";
break;
case KB_DOWN:
std::cout << "down\n";
break;
case KB_RIGHT:
std::cout << "right\n";
break;
case KB_LEFT:
std::cout << "left\n";
break;
default: std::cout << "unknown\n";
}
}
else if (ch == ESC)
{
std::cout << "Escape pressed, going out!\n";
break;
}
}
}
代替
_getchar()
那个视觉工作室(我用来编写和运行我的鳕鱼) 给出错误, 我也把它放在一个循环中,直到你按下 Escape 底部。