어떻게 리눅스에서 즉시 키 스트로크를 캡처 할 수 있습니까?[중복]

StackOverflow https://stackoverflow.com//questions/12710582

  •  13-12-2019
  •  | 
  •  

문제

가능한 중복:
리눅스에서 게치()와 게치()에 해당하는 것은 무엇입니까?

나는 리눅스 프로그래밍에 초보자입니다.:-)

난 그냥 내 프로그램(사용 C 언어)는 리눅스에서 모든 단일 키 스트로크를 즉시 캡처 한 다음 에코할지 여부를 결정하고 텔넷처럼 표시하는 방법을 결정할 수 있습니다.

예를 들어,사용자가'에이'를 치면 프로그램이'비'를 표시하기를 원합니다.

그것은 재미 있고 쓸모없는 소리.나는 그것에 대해 단지 궁금합니다.

도움이 되었습니까?

해결책

기본적으로 즉시 정의하는 방법에 크게 의존합니다.

여기에 두 가지 작업이 있습니다.첫 번째는 대부분의 입력 라이브러리에 내장된 일반 키 반향을 비활성화하는 것입니다.두 번째는 이전 문자 대신 새로운 문자를 인쇄하는 것입니다.

의사 코드에서

 echo(off);
 while (capturing && charIsAvailable()) {
   c = readOneChar();
   if (c == '\n') {
     capturing = false;
   }
   printf("%c", c++);
 }
 echo(on);

키를 누르는 것을 캡처하기 위해 통신하는 여러 시스템이 있습니다.

  1. 키보드
  2. (아마도)
  3. 인터럽트 처리기
  4. 운영 체제
  5. 윈도우 서버 프로세스
  6. 초점이있는 엑스"창".

마지막 단계는 엑스 서버에서 이벤트를 캡처하고 처리하는 연속 루프를 실행하는 프로그램으로 수행됩니다.당신이 특정 방법으로이 프로그램을 확장하고 싶다면(키를 누를 시간의 길이를 얻을)당신은 당신이 정말로 완전히"요리"문자를 수신 할 수 없다는 것을 의미"원시"키보드 이벤트를 원하는 다른 프로그램을 말할 필요가있다.그 결과,당신은 어떤 키가 위아래로,그리고 얼마나 오래 있는지 추적해야 할 것이고,당신의 프로그램에서 모든 이상한 메타 키 동작을 처리해야 할 것입니다. 시프트 다운 등).

또한 이벤트를 줄 지향 청크(줄 이벤트)또는 문자 지향 청크(문자 이벤트)로 수신할지 여부를 제어하는 표준 및 비 표준과 같이 고려해야 할 다른 처리 모드가 있습니다.다시 말하지만,이것은 업스트림 프로그램이 다운스트림 클라이언트의 요구 사항을 인식하도록 해야하기 때문에 다소 복잡합니다.

이제 환경에 대한 아이디어를 얻었으므로 문자 출력을 억제하는 데 필요한 실제 코드를 다시 살펴 보겠습니다.

// define a terminal configuration data structure
struct termios term;

// copy the stdin terminal configuration into term
tcgetattr( fileno(stdin), &term );

// turn off Canonical processing in term
term.c_lflag &= ~ICANON;

// turn off screen echo in term
term.c_lflag &= ~ECHO;

// set the terminal configuration for stdin according to term, now
tcsetattr( fileno(stdin), TCSANOW, &term);


(fetch characters here, use printf to show whatever you like)

// turn on Canonical processing in term
term.c_lflag |= ICANON;

// turn on screen echo in term
term.c_lflag |= ECHO;

// set the terminal configuration for stdin according to term, now
tcsetattr( fileno(stdin), TCSANOW, &term);

심지어 이것은 즉각적인 것이 아닙니다.즉시 얻으려면,당신은 결국 커널 모듈(여전히 스위치가 실제로 닫히는 순간으로 즉각적인되지 않습니다 키보드 마이크로 컨트롤러만큼 즉각적인되지 않습니다)를 의미 소스에 가까이해야합니다.소스와 대상 사이에 충분한 항목이 있으면 결국 차이를 알 수 있습니다.그러나 실제로이 코드는 성능과 유연성 사이의 최상의 트레이드 오프를 찾는 사람들에 의해 많이 작업되었습니다.

다른 팁

에드윈 버크 훌륭한 대답을 제공했습니다.여기 또 다른 대안이 있습니다. ncurses 그런 것들을 좀 더 쉽게 만들고 거의 모든 리눅스 배포판 및 기타 유닉스 변종에서 지원됩니다.

#include <ncurses.h>

int main(int argc, char *argv[])
{
    int ch,c;
    initscr();
    cbreak();
    noecho();

    while( ch != 'q')
    {
        switch( c = getch() )
        {
            case 'a':
                ch = 'b';
            break;

            case 'b':
                ch = 'c';
            break;

            case 'c':
                ch = 'd';
            break;

            default:
                ch = c;                 
            break;
        }
        printw("%c",ch);
    }
    endwin();
    return(0);
}

코드를 사용하여 컴파일하십시오.쨩챌쨔챈쨀

그리고 여기에 몇 가지 지원 링크가 있습니다:

노에초 및 기타-맨 페이지
프로그래밍 하우투

이 코드는 인터넷에서 찾을 수 있으며 kermi3 에서 씨 보드

#include <termios.h>
#include <unistd.h>

int mygetch(void)
{
    struct termios oldt,newt;
    int ch;
    tcgetattr( STDIN_FILENO, &oldt );
    newt = oldt;
    newt.c_lflag &= ~( ICANON | ECHO );
    tcsetattr( STDIN_FILENO, TCSANOW, &newt );
    ch = getchar();
    tcsetattr( STDIN_FILENO, TCSANOW, &oldt );
    return ch;
}

편집: 물론 당신 문 를 고 싶 경 고 스 값 변경 char 대신 int

과잉 일 수 있지만 다음과 같은 게임 라이브러리를 사용할 수 있습니다 2015 년 그것을 달성하기 위해.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top