[완료] getchar() 함수에서 대기중일 때 키보드 입력 말고 해제하는 방법이 있을까요?

hahaite의 이미지

안녕하세요.

getchar() 함수를 사용할 때요.

위 함수에서 키보드 입력이 있을 때까지 대기상태로 들어가잖아요.
혹시 키보드를 누르지 않고 위 함수의 대기상태를 해제하는 방법이 있을까요?

알려주심 고맙겠습니다.

ymir의 이미지

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 』

hahaite의 이미지

질문의 의도를 잘못 이해하신 듯 합니다.

예를 들어 while() 문에 아래와 같이 getchar() 를 쓴다고 할 때,
키보드를 눌러야만 while() 문을 빠져나갈 수 있잖아요.

제 질문은 키보드를 누르지 않고 아래 while() 문을 빠져나가는 방법이 있는가를
묻는 것입니다.

while(1)
{
ch = getchar();

if(ch)
break ;
}

^^

snowall의 이미지

ymir님이 맞게 이해하신 것 같은데요?

키보드를 누르지 않는다면, 컴퓨터가 알아서 나가라고 하든가 해야 할 것 같은데요. 마우스 입력을 받든지, 타임아웃을 걸든지, 어떻든 ymir님의 방법을 써야 할 거라는 생각이 듭니다.

피할 수 있을때 즐겨라! http://melotopia.net/b

upersbird의 이미지

종료 조건이 키입력이 아니시면 타이머나 다른 인터럽트가 있을텐데요..
어떤 종료 조건을 말씀하시는건가요?
(궁금해서 댓글을...ㅎㅎ)

익명 사용자의 이미지

관심 가져주신 분들께 감사드리며,

아래 링크를 따라가시면 예전에 올린 질문 내용을 보실 수 있습니다.
안타깝게도 그 시절 답변을 못받았구요.

코드보다도 코드 아래 설명된 부분을 보시면 질문의 의도를 아시리라 봅니다.

http://oops.kldp.org/node/112224

ymir의 이미지

흠.. 그리 간단한 문제가 아니었군요.

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 』

bushi의 이미지

대충 아무렇게나해도 될 것 같은데요.

#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;
}

termio 부분은 http://www.faqs.org/faqs/unix-faq/programmer/faq/ 의 "3.2 How can I read single characters from the terminal?" 에 있는 코드입니다.
ECHO 만 추가로 더 꺼버렸습니다.
hahaite의 이미지

ㅎㅎ 대충하기엔 공부할 부분이 살짝 있네요.

잘 동작하는 것 확인하였습니다.

답변 고맙습니다. _(__)_

^^

댓글 달기

Filtered HTML

  • 텍스트에 BBCode 태그를 사용할 수 있습니다. URL은 자동으로 링크 됩니다.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>
  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <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].
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.

BBCode

  • 텍스트에 BBCode 태그를 사용할 수 있습니다. URL은 자동으로 링크 됩니다.
  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <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].
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param>
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.

Textile

  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <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].
  • You can use Textile markup to format text.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>

Markdown

  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <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].
  • Quick Tips:
    • Two or more spaces at a line's end = Line break
    • Double returns = Paragraph
    • *Single asterisks* or _single underscores_ = Emphasis
    • **Double** or __double__ = Strong
    • This is [a link](http://the.link.example.com "The optional title text")
    For complete details on the Markdown syntax, see the Markdown documentation and Markdown Extra documentation for tables, footnotes, and more.
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>

Plain text

  • HTML 태그를 사용할 수 없습니다.
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.
  • 줄과 단락은 자동으로 분리됩니다.
댓글 첨부 파일
이 댓글에 이미지나 파일을 업로드 합니다.
파일 크기는 8 MB보다 작아야 합니다.
허용할 파일 형식: txt pdf doc xls gif jpg jpeg mp3 png rar zip.
CAPTCHA
이것은 자동으로 스팸을 올리는 것을 막기 위해서 제공됩니다.