게치 및 화살표 코드
지금 프로그램을 만들고 있는데getch()화살표 키를 스캔합니다.지금까지의 코드는 다음과 같습니다.
switch(getch()) {
case 65: // key up
break;
case 66: // key down
break;
case 67: // key right
break;
case 68: // key left
break;
}
문제는 이 버튼을 누르면'A','B','C'또는'D'코드도 실행됩니다.왜냐하면65의 10진수 코드입니다.'A'등...
다른 사람에게 연락하지 않고 화살표 키를 확인할 수 있는 방법이 있나요?
감사합니다!
화살표 키 하나를 누르면getch는 다음 3가지 값을 버퍼에 푸시합니다.
'\033''[''A','B','C'또는'D'
코드는 다음과 같습니다.
if (getch() == '\033') { // if the first value is esc
getch(); // skip the [
switch(getch()) { // the real value
case 'A':
// code for arrow up
break;
case 'B':
// code for arrow down
break;
case 'C':
// code for arrow right
break;
case 'D':
// code for arrow left
break;
}
}
getch() 함수는 FatalError의 설명에서 언급된 대로 화살표 키(및 다른 일부 특수 키)에 대한 두 개의 키 코드를 반환합니다.먼저 0(0x00) 또는 224(0xE0) 중 하나를 반환하고 누른 키를 식별하는 코드를 반환합니다.
화살표 키의 경우 먼저 224를 반환한 후 72(위), 80(아래), 75(왼쪽) 및 77(오른쪽)을 반환합니다.Num-Pad 화살표 키(NumLock이 꺼진 상태)를 누르면 getch()가 224가 아닌 0을 먼저 반환합니다.
getch()는 어떤 방식으로도 표준화되지 않았으며 이러한 코드는 컴파일러마다 다를 수 있습니다.이러한 코드는 Windows의 MinGW 및 Visual C++에 의해 반환됩니다.
다양한 키에 대한 getch()의 동작을 볼 수 있는 편리한 프로그램은 다음과 같습니다.
#include <stdio.h>
#include <conio.h>
int main ()
{
int ch;
while ((ch = _getch()) != 27) /* 27 = Esc key */
{
printf("%d", ch);
if (ch == 0 || ch == 224)
printf (", %d", _getch ());
printf("\n");
}
printf("ESC %d\n", ch);
return (0);
}
이것은 MinGW 및 Visual C++에서 동작합니다.이러한 컴파일러는 getch() 대신 _getch()라는 이름을 사용하여 비표준 함수임을 나타냅니다.
따라서 다음과 같은 작업을 수행할 수 있습니다.
ch = _getch ();
if (ch == 0 || ch == 224)
{
switch (_getch ())
{
case 72:
/* Code for up arrow handling */
break;
case 80:
/* Code for down arrow handling */
break;
/* ... etc ... */
}
}
그래서 나는 많은 노력 끝에 기적적으로 이 영원한 문제를 해결했다! 나는 리눅스 단말기를 흉내내려고 하다가 위 화살표 키나 아래 화살표 키를 누르면 접근할 수 있는 명령어 이력을 유지하는 부분에서 꼼짝할 수 없었다.나는 ncurses lib가 이해하기 어렵고 배우는 것이 느리다는 것을 알았다.
char ch = 0, k = 0;
while(1)
{
ch = getch();
if(ch == 27) // if ch is the escape sequence with num code 27, k turns 1 to signal the next
k = 1;
if(ch == 91 && k == 1) // if the previous char was 27, and the current 91, k turns 2 for further use
k = 2;
if(ch == 65 && k == 2) // finally, if the last char of the sequence matches, you've got a key !
printf("You pressed the up arrow key !!\n");
if(ch == 66 && k == 2)
printf("You pressed the down arrow key !!\n");
if(ch != 27 && ch != 91) // if ch isn't either of the two, the key pressed isn't up/down so reset k
k = 0;
printf("%c - %d", ch, ch); // prints out the char and it's int code
좀 대담하지만 많은 것을 설명해준다.행운을 빕니다.
그럼 사용자 단말기의 키보드가 기능 키를 단일 값으로 해석할 수 있습니다(즉, 이스케이프 시퀀스 없음).
man 페이지에 기재된 바와 같이:
키패드 옵션은 사용자 단말기의 키패드를 활성화합니다.활성화(bf가 TRUE)된 경우 사용자는 기능 키(화살표 키 등)를 누를 수 있으며 wgetch는 KEY_LEFT와 같이 기능 키를 나타내는 단일 값을 반환합니다.비활성화(bf가 FALSE)된 경우, 저주는 기능 키를 특별히 취급하지 않으며 프로그램은 이스케이프 시퀀스 자체를 해석해야 합니다.단말기의 키패드를 온(송신 가능) 또는 오프(로컬 동작 가능)할 수 있는 경우, 이 옵션을 온으로 하면, wgetch 가 호출되었을 때에 단말기의 키패드가 온이 됩니다.키패드의 기본값은 false 입니다.
하는 ncurses동작 코드와 ncurses의 초기화를 사용하여 getchar()는 위 화살표 키와 아래 화살표 키에 대해 동일한 값(27)을 반환합니다.
이것을 시도해 보는 것은 어떤가?
void CheckKey(void) {
int key;
if (kbhit()) {
key=getch();
if (key == 224) {
do {
key=getch();
} while(key==224);
switch (key) {
case 72:
printf("up");
break;
case 75:
printf("left");
break;
case 77:
printf("right");
break;
case 80:
printf("down");
break;
}
}
printf("%d\n",key);
}
int main() {
while (1) {
if (kbhit()) {
CheckKey();
}
}
}
(224 의 이유를 알 수 없는 경우는, 다음의 코드를 실행해 주세요).
#include <stdio.h>
#include <conio.h>
int main() {
while (1) {
if (kbhit()) {
printf("%d\n",getch());
}
}
}
왜 224인지 모르겠는데 왜 224인지 알면 댓글 좀 써주시겠어요?
실제로 화살표 키를 읽으려면 스캔 코드를 읽어야 한다.다음은 화살표 키를 누를 때 생성되는 스캔 코드입니다(키 해제 아님).
num Lock이 꺼져 있는 경우
- 좌측 E0 4B
- 오른쪽 E0 4D
- 업 E0 48
- 다운 E0 50
Num Lock이 켜져 있는 경우 이러한 키 앞에 E0 2A가 표시됩니다.
- 바이트 E0은 -32
- 바이트 48은 72 UP입니다.
바이트 50은 80 DOWN입니다.
user_var=getch(); if(user_var == -32) { user_var=getch(); switch(user_var) { case 72: cur_sel--; if (cur_sel==0) cur_sel=4; break; case 80: cur_sel++; if(cur_sel==5) cur_sel=1; break; } }
위의 코드에서 나는 프로그래머가 4줄만 이동하기를 원한다고 가정했다.
이거 드셔보세요.
Windows 7 의 코드:블록
while (true)
{
char input;
input = getch();
switch(input)
{
case -32: //This value is returned by all arrow key. So, we don't want to do something.
break;
case 72:
printf("up");
break;
case 75:
printf("left");
break;
case 77:
printf("right");
break;
case 80:
printf("down");
break;
default:
printf("INVALID INPUT!");
break;
}
}
getch를 사용하여 화살표 코드를 취득하는 함수를 작성했습니다.빠른 해결 방법이지만, 함수는 화살표 키에 따라 ASCII 코드를 반환합니다: UP : -10 DOWN : -11 RIGHT : -12 LEFT : -13
또한 이 기능을 통해 Escape 터치와 화살표 키를 구분할 수 있습니다.하지만 ESC 키를 활성화하려면 ESC를 두 번 눌러야 합니다.
코드는 다음과 같습니다.
char getch_hotkey_upgrade(void)
{
char ch = 0,ch_test[3] = {0,0,0};
ch_test[0]=getch();
if(ch_test[0] == 27)
{
ch_test[1]=getch();
if (ch_test[1]== 91)
{
ch_test[2]=getch();
switch(ch_test[2])
{
case 'A':
//printf("You pressed the up arrow key !!\n");
//ch = -10;
ch = -10;
break;
case 'B':
//printf("You pressed the down arrow key !!\n");
ch = -11;
break;
case 'C':
//printf("You pressed the right arrow key !!\n");
ch = -12;
break;
case 'D':
//printf("You pressed the left arrow key !!\n");
ch = -13;
break;
}
}
else
ch = ch_test [1];
}
else
ch = ch_test [0];
return ch;
}
난 그저 시작일 뿐인데, 하지만 내가 만든 건char(for example "b")는 , , , 을 합니다.b = _getch();은 (그것은)conio.h command) 및 합니다.
If (b == -32)
b = _getch();
키를 확인합니다(위 72, 아래 80, 오른쪽 77, 왼쪽 75).
void input_from_key_board(int &ri, int &ci)
{
char ch = 'x';
if (_kbhit())
{
ch = _getch();
if (ch == -32)
{
ch = _getch();
switch (ch)
{
case 72: { ri--; break; }
case 80: { ri++; break; }
case 77: { ci++; break; }
case 75: { ci--; break; }
}
}
else if (ch == '\r'){ gotoRowCol(ri++, ci -= ci); }
else if (ch == '\t'){ gotoRowCol(ri, ci += 5); }
else if (ch == 27) { system("ipconfig"); }
else if (ch == 8){ cout << " "; gotoRowCol(ri, --ci); if (ci <= 0)gotoRowCol(ri--, ci); }
else { cout << ch; gotoRowCol(ri, ci++); }
gotoRowCol(ri, ci);
}
}
언급URL : https://stackoverflow.com/questions/10463201/getch-and-arrow-codes
'programing' 카테고리의 다른 글
| 오픈에서의 r과 rb의 차이점은 무엇입니까? (0) | 2022.08.30 |
|---|---|
| 이클립스 코멘트/댓글 없음 바로가기? (0) | 2022.08.30 |
| 양방향 JPA OneToMany/ManyToOne 어소시에이션의 '어소시에이션의 역방향'이란 무엇입니까? (0) | 2022.08.30 |
| vue 웹 팩에 바우어 구성 요소 추가 (0) | 2022.08.30 |
| Vuex 상태 개체에서 키로 항목을 삭제할 때 getter에 바인딩된 계산된 속성이 업데이트되지 않음 (0) | 2022.08.29 |