차단하지 않고 UNIX 콘솔 앱에서 단일 키 스트로크를 어떻게 캡처하려면?
문제
C로 작성된 매우 간단한 TCP 서버가 있습니다. 연결을 기다리는 동안 무기한 실행됩니다. Windows에서는 사용합니다 select
소켓의 활동을 확인하고 키보드에서 'Q'를 누르면 다음 코드가 없으면 다음 코드가 있습니다.
if( kbhit() ) {
char c = getch();
if( c == 'q' ) break;
}
이것은 유닉스에서는 작동하지 않습니다 kbhit
존재하지 않습니다 getch
다르게 작동합니다. 나는 일부를 찾았다 샘플 코드 그것은 사용합니다 tcsetattr
터미널 설정을 변경하고 문자 별 입력을 허용합니다. init 함수를 호출 한 후 /dev /stdin을 열었습니다 ( O_NONBLOCK
)) 그리고 캐릭터를 읽으십시오 read( f, &c, 1 )
캐릭터가 맞을 때까지 차단됩니다.
나는 별도의 스레드를 스폰하고 그것 사용자가 'Q'를 쳤을 때 무기한 대기 한 다음 첫 번째 스레드에 신호를 보내지 만 약간 무겁게 보입니다. 더 쉬운 방법이 있습니까?
해결책
선택 핸들 목록에 stdin을 추가하고 데이터가있는 경우 읽기로 전화하여 하나의 문자를 읽으십시오.
다른 팁
오히려, 당신의 "f"를 추가하십시오
read( f, &c, 1 )
전화를 선택합니다. F가 읽을 준비가되면 문자가 눌려졌으며 read ()가 차단되지 않습니다.
UNIX에서 시스템 콘솔 또는 X 터미널 창에서 키보드 I/O는 가상 터미널을 통과합니다. 장치 /dev /tty는 요즘 프로세스 제어 터미널에 액세스하는 일반적인 방법입니다. Open/Close/Read/Write 이외의 장치 조작은 모두 IOCTL (2) 시스템에 의해 처리됩니다. 당신이하고 싶은 일에 대한 일반적인 아이디어는
제어 터미널을 엽니 다 (stdin이거나 아닐 수도 있음)
전체 입력 라인을 기다리지 않고 해당 터미널의 작동 모드를 변경합니다 (정상 기본값).
해당 터미널 (stdin 일 수 있음)에서 읽는 것이 오류 또는 종료 조건이 없으면 부분 줄 또는 제로 문자를 반환 할 수 있음을 알면 나머지 프로그램을 계속하십시오.
두 번째 단계를 수행하는 방법에 대한 자세한 답변은 C- 프로그래밍 FAQ. 또한 이것은 언어 질문이 아니라 OS 질문이라고 지적합니다. 그들은 9 가지 가능성을 제공하지만이 질문과 관련된 세 가지 주요 기능은
- Curses (3) 라이브러리를 사용하십시오
- 오래된 BSD 스타일 시스템, sgttyb를 사용하여 cbreak 또는 raw를 설정합니다.
- posix 또는 기존 시스템 v 스타일 시스템, tcgetaw/tcsetaw를 사용하여 c_cc [vmin]을 1로, c_cc [vtime]을 0으로 설정하십시오.
C FAQ에서 몇 가지 언급을 따라 KBHIT 코드 조각 의이 페이지.