안녕하세요.
getchar() 함수를 사용할 때요.
위 함수에서 키보드 입력이 있을 때까지 대기상태로 들어가잖아요. 혹시 키보드를 누르지 않고 위 함수의 대기상태를 해제하는 방법이 있을까요?
알려주심 고맙겠습니다.
state 가 변하려면 먼저 어떠한 조건이나 이벤트가 trigger 되어야 겠죠.
단순히 조건이 시간이라면 signal handler 에 SIGALRM 등록해 놓고, alarm 먼저 호출해 주면 되겠네요.
다른게 더 있다면 multi-thread 로 getchar 를 사용하는 thread 를 제어하게끔 구현해도 되겠구요.
되면 한다! / feel no sorrow, feel no pain, feel no hurt, there's nothing gained.. only love will then remain.. 『 Mizz 』
질문의 의도를 잘못 이해하신 듯 합니다.
예를 들어 while() 문에 아래와 같이 getchar() 를 쓴다고 할 때, 키보드를 눌러야만 while() 문을 빠져나갈 수 있잖아요.
제 질문은 키보드를 누르지 않고 아래 while() 문을 빠져나가는 방법이 있는가를 묻는 것입니다.
while(1) { ch = getchar();
if(ch) break ; }
^^
ymir님이 맞게 이해하신 것 같은데요?
키보드를 누르지 않는다면, 컴퓨터가 알아서 나가라고 하든가 해야 할 것 같은데요. 마우스 입력을 받든지, 타임아웃을 걸든지, 어떻든 ymir님의 방법을 써야 할 거라는 생각이 듭니다.
피할 수 있을때 즐겨라! http://melotopia.net/b
종료 조건이 키입력이 아니시면 타이머나 다른 인터럽트가 있을텐데요.. 어떤 종료 조건을 말씀하시는건가요? (궁금해서 댓글을...ㅎㅎ)
관심 가져주신 분들께 감사드리며,
아래 링크를 따라가시면 예전에 올린 질문 내용을 보실 수 있습니다. 안타깝게도 그 시절 답변을 못받았구요.
코드보다도 코드 아래 설명된 부분을 보시면 질문의 의도를 아시리라 봅니다.
http://oops.kldp.org/node/112224
흠.. 그리 간단한 문제가 아니었군요.
signal handler 로 점프해도 getchar 에서 다시 대기타는군요. strace 떠 보니까, read(0, .., 1) 에서 ERESTARTSYS 가 리턴됩니다.
아마도 signal 에 SA_RESTART 가 켜진 것 같은데, SA_RESTART 를 끄고 sigaction 으로 호출하면.. 적어도 timeout 은 가능하겠네요.
대충 아무렇게나해도 될 것 같은데요.
#include <stdio.h> #include <sys/time.h> #include <sys/types.h> #include <termios.h> #include <fcntl.h> #include <unistd.h> #include <pthread.h> static int poll_getch[2] = {-1, -1}; void cancel_getch(void) { int fd = poll_getch[0]; if (fd >= 0) write(poll_getch[1], &fd, 1); } int getch(void) { int fd_cancel = poll_getch[0]; int fd_stdin = fileno(stdin); int ch = -1; struct termios org_term, new_term; tcgetattr(fd_stdin, &org_term); new_term = org_term; new_term.c_lflag &= ~(ICANON | ECHO); new_term.c_cc[VTIME] = 0; new_term.c_cc[VMIN] = 1; tcsetattr(fd_stdin, TCSANOW, &new_term); fd_set rdfds; FD_ZERO(&rdfds); FD_SET(fd_stdin, &rdfds); FD_SET(fd_cancel, &rdfds); int max_fd = fd_stdin > fd_cancel ? fd_stdin : fd_cancel; int r = select(max_fd + 1, &rdfds, NULL, NULL, NULL); if (r > 0 && FD_ISSET(fd_stdin, &rdfds)) ch = getchar(); tcsetattr(fd_stdin, TCSANOW, &org_term); return ch; } void *test_timer(void *arg) { sleep(5); cancel_getch(); return NULL; } int main(int argc, char **argv) { if (pipe(poll_getch) < 0) { perror("pipe"); return 1; } pthread_t test; pthread_create(&test, NULL, test_timer, NULL); while (1) { int ch = getch(); if (ch < 0) { printf("canceled\n"); break; } printf("ch:%x\n", ch); } return 0; }
ㅎㅎ 대충하기엔 공부할 부분이 살짝 있네요.
잘 동작하는 것 확인하였습니다.
답변 고맙습니다. _(__)_
텍스트 포맷에 대한 자세한 정보
<code>
<blockcode>
<apache>
<applescript>
<autoconf>
<awk>
<bash>
<c>
<cpp>
<css>
<diff>
<drupal5>
<drupal6>
<gdb>
<html>
<html5>
<java>
<javascript>
<ldif>
<lua>
<make>
<mysql>
<perl>
<perl6>
<php>
<pgsql>
<proftpd>
<python>
<reg>
<spec>
<ruby>
<foo>
[foo]
음 ..
state 가 변하려면 먼저 어떠한 조건이나 이벤트가 trigger 되어야 겠죠.
단순히 조건이 시간이라면 signal handler 에 SIGALRM 등록해 놓고, alarm 먼저 호출해 주면 되겠네요.
다른게 더 있다면 multi-thread 로 getchar 를 사용하는 thread 를 제어하게끔 구현해도 되겠구요.
되면 한다! / feel no sorrow, feel no pain, feel no hurt, there's nothing gained.. only love will then remain.. 『 Mizz 』
답변 고맙습니다.
질문의 의도를 잘못 이해하신 듯 합니다.
예를 들어 while() 문에 아래와 같이 getchar() 를 쓴다고 할 때,
키보드를 눌러야만 while() 문을 빠져나갈 수 있잖아요.
제 질문은 키보드를 누르지 않고 아래 while() 문을 빠져나가는 방법이 있는가를
묻는 것입니다.
while(1)
{
ch = getchar();
if(ch)
break ;
}
^^
ymir님이 맞게 이해하신 것 같은데요? 키보드를
ymir님이 맞게 이해하신 것 같은데요?
키보드를 누르지 않는다면, 컴퓨터가 알아서 나가라고 하든가 해야 할 것 같은데요. 마우스 입력을 받든지, 타임아웃을 걸든지, 어떻든 ymir님의 방법을 써야 할 거라는 생각이 듭니다.
피할 수 있을때 즐겨라! http://melotopia.net/b
조건이..
종료 조건이 키입력이 아니시면 타이머나 다른 인터럽트가 있을텐데요..
어떤 종료 조건을 말씀하시는건가요?
(궁금해서 댓글을...ㅎㅎ)
예전에 질문드린 링크 확인 부탁드립니다.
관심 가져주신 분들께 감사드리며,
아래 링크를 따라가시면 예전에 올린 질문 내용을 보실 수 있습니다.
안타깝게도 그 시절 답변을 못받았구요.
코드보다도 코드 아래 설명된 부분을 보시면 질문의 의도를 아시리라 봅니다.
http://oops.kldp.org/node/112224
음 ..
흠.. 그리 간단한 문제가 아니었군요.
signal handler 로 점프해도 getchar 에서 다시 대기타는군요.
strace 떠 보니까, read(0, .., 1) 에서 ERESTARTSYS 가 리턴됩니다.
아마도 signal 에 SA_RESTART 가 켜진 것 같은데, SA_RESTART 를 끄고 sigaction 으로 호출하면..
적어도 timeout 은 가능하겠네요.
되면 한다! / feel no sorrow, feel no pain, feel no hurt, there's nothing gained.. only love will then remain.. 『 Mizz 』
대충 아무렇게나해도 될 것 같은데요. #include
대충 아무렇게나해도 될 것 같은데요.
termio 부분은 http://www.faqs.org/faqs/unix-faq/programmer/faq/ 의 "3.2 How can I read single characters from the terminal?" 에 있는 코드입니다.
ECHO 만 추가로 더 꺼버렸습니다.
잘 동작합니다.
ㅎㅎ 대충하기엔 공부할 부분이 살짝 있네요.
잘 동작하는 것 확인하였습니다.
답변 고맙습니다. _(__)_
^^
댓글 달기