programing

게치 및 화살표 코드

prostudy 2022. 8. 30. 21:29
반응형

게치 및 화살표 코드

지금 프로그램을 만들고 있는데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

반응형