키보드 방향키, 탭키 입력제어?
글쓴이: beeswing / 작성시간: 일, 2004/09/19 - 5:25오후
리눅스에서 쉘(shell : bash나 csh같은) 구현을 하고 있습니다.
제가 부딪힌 부분은, ls 나 cat 등의 명령어를 치는 중간에
화살표 방향키를 위로 누르면, 전에 입력했던 명령어들이 나오는
history 기능입니다...
근데, 방향키나 탭키를 인식하는 부분이 정말 애매하네요...
getch() 가 할 수 있는데 아쉽게도 DOS 전용이군요...
getchar() 나 scanf() 로는 입력도중에 키를 인식하는게 불가능한 것 같습니다.
꼭 엔터키를 쳐야하니까요...
키보드제어를 도와주는 ncurses 라는 외부라이브러리가 있다는 건 알아냈는데,
외부 라이브러리를 사용하는 건 지양해야 하기때문에 어렵습니다...
꽁수를 알려주세요~~
Forums:


-.-
스티븐스.. advanced programmng in the unix ennvironment
책의 터미널 부분을 공부해보세요..
거기에 있어요 ^^;
터미널 IO부분에 있습니다.
readline 라이브러리를 사용해 보시는건 어떨까요? bash의 그런
readline 라이브러리를 사용해 보시는건 어떨까요? bash의 그런 기능이 readline 라이브러리로 구현되어 있습니다.
http://directory.fsf.org/readline.html
--
익스펙토 페트로눔
숙제이고 외부 라이브러리를 쓰는 걸 지양하라고 했으니 readline을
숙제이고 외부 라이브러리를 쓰는 걸 지양하라고 했으니 readline을 쓰는 것도 아마 안 될 듯 하군요.
'손님'분 말씀대로 -_- Terminal I/O를 쓰는 것이...
그 스티븐스 책에 보면 일반적인 라인 단위 인풋이 아닌 Non-canonical mode로 터미널을 제어하는 것에 대해 나와 있습니다. 그걸 이용하셔야 할 듯.
노루가 사냥꾼의 손에서 벗어나는 것 같이, 새가 그물치는 자의 손에서 벗어나는 것 같이 스스로 구원하라 -잠언 6:5
예전에 비슷한 프로그램 짠게 있어서, 그 일부분을 발췌했습니다.도움이
예전에 비슷한 프로그램 짠게 있어서, 그 일부분을 발췌했습니다.
도움이 되실지 모르겠네요. 프로그램 시작시에 cmd_prepare()를 호출하시면, non-canonical 모드로 진입하게 됩니다. 기타 설정은 책을 참조하시고요.
프로그램 종료시에는 cmd_restore()를 호출하시면 됩니다.
프로그램 중반부에 cmd_peek()을 주기적으로 호출하시고, 실제 처리부분은 cmd_handler()를 구현하시면 됩니다.
static struct termios tsaved; BOOL bsaved=FALSE; void cmd_prepare() { struct termios tnew; // setvbuf(stdout,NULL,_IONBF,0); // setvbuf(stdin,NULL,_IONBF,0); if(isatty(0) && tcgetattr(0,&tsaved) >= 0) { bsaved=TRUE; memcpy(&tnew,&tsaved,sizeof(tsaved)); // tnew.c_lflag &= ~(ICANON|ECHO); tnew.c_lflag &= ~(ICANON|ECHO|ISIG); // tcsetattr(0,TCSAFLUSH,&tnew); tcsetattr(0,TCSANOW,&tnew); } else bsaved=FALSE; VWIN_Start(); } void cmd_restore() { if(bsaved) { // tcsetattr(0,TCSAFLUSH,&tsaved); tcsetattr(0,TCSANOW,&tsaved); // setvbuf(stdout,NULL,_IOLBF,0); // setvbuf(stdin,NULL,_IOLBF,0); bsaved=FALSE; } VWIN_End(); } int cmd_peek(long seconds, int peek) { struct timeval timeout; fd_set readfds; if(peek) return peek; FD_ZERO(&readfds); FD_SET(0,&readfds); timeout.tv_sec = seconds; timeout.tv_usec = 0; if(select(1,&readfds,NULL,NULL,&timeout)) return cmd_handler(fgetc(stdin)); else return CMD_NONE; }댓글 달기