2011-08-10 4 views
2

저는 명령 줄에서 사용자 입력을 받아들이는 LInux/C++의 간단한 콘솔 응용 프로그램을 작성하고 있습니다. 스레드에서 std::getline(std::cin)/std::cin >> text을 (를) 사용하고 있습니다.stdin에서 읽기를 중지하십시오.

10 초 후 콘솔 입력을받지 않고 텍스트 메시지를 작성한 다음 다른 작업을 수행하고 싶습니다. 타이머 용으로 별도의 스레드를 사용하고 있습니다.

사용자가 텍스트를 삽입하지 않을 때까지 10 초가 경과했는지 확인할 수 없으므로이 방법이 작동하지 않습니다.

텍스트를 승인하는 응용 프로그램을 중지하고 다른 줄로 이동하는 더 좋은 방법이 있습니까? settimer 및 신호 프로그래밍을 사용하려고 생각했지만 단순화를 위해 다른 스레드에서 호출 할 항목이 필요합니다.

감사

AFG는

+2

는 새로운 스레드에서 입력을 읽은 다음 주 스레드에서 스레드를 죽일 수 십초이 경과 한 후에? – GWW

+1

@ GWW의 제안 외에 항상 낮은 수준의 OS 기능을 사용할 수 있습니다. Linux/* nix에서는 "원시"I/O라고 불렀습니다. 그러나 그 일을한지 오래되었습니다. –

답변

5

당신은 ncurses 사용하거나 당신이하지 않으려면이 blog post에 설명 된대로, 당신은 선택 사용할 수 있습니다. 기본적으로 select을 사용하고 제한 시간을 지정할 수 있습니다. stdin FD가 설정되면 안전하게 읽을 수 있으며 차단되지 않습니다. 선택에 대한 자세한 정보가 필요하면 this out과 물론 Wikipedia을 확인하십시오. 그것은 알기에 편리한 전화입니다. 예를 들어,

// if != 0, then there is data to be read on stdin 

int kbhit() 
{ 
    // timeout structure passed into select 
    struct timeval tv; 
    // fd_set passed into select 
    fd_set fds; 
    // Set up the timeout. here we can wait for 1 second 
    tv.tv_sec = 1; 
    tv.tv_usec = 0; 

    // Zero out the fd_set - make sure it's pristine 
    FD_ZERO(&fds); 
    // Set the FD that we want to read 
    FD_SET(STDIN_FILENO, &fds); //STDIN_FILENO is 0 
    // select takes the last file descriptor value + 1 in the fdset to check, 
    // the fdset for reads, writes, and errors. We are only passing in reads. 
    // the last parameter is the timeout. select will return if an FD is ready or 
    // the timeout has occurred 
    select(STDIN_FILENO+1, &fds, NULL, NULL, &tv); 
    // return 0 if STDIN is not ready to be read. 
    return FD_ISSET(STDIN_FILENO, &fds); 
} 

는 스레드가 이것에 대한 과잉이다 Peek stdin using pthreads

+0

와우. 나는 재미있는 것을 읽을 것 같다. 고마워. 나는 많은 흥미로운 일들을 할 수있는 것 같아 보입니다. 알려 드리겠습니다. –

+0

안녕하세요. 나는 약간의 지연을 가지고 테스트했다. 그것은 작동하지만 kbhit() 후에 버퍼를 소비하는 코드가 필요합니다. 나는 아래에 그것으로 대답했다. 고마워요! –

2

에이 SO 질문을 참조하십시오. 입력 루프에서 select()를 사용하여 stdin이 읽을 준비가되었는지 확인합니다. 시간()에 대한 호출을 통해 시간을 확인하고 10 초가 경과하면 루프를 종료 할 수 있습니다.

0

그것은 잘 작동하지만 바이트를 '소비'하는 코드가 필요합니다. 당신의 kbhit()의 사용 아래

:

int main(int argc, const char** argv){ 
    while(!kbhit()){ 
     // do whatever you want here while 
     // entering the text 
     std::cout << "..while you write!" << std::endl; 
    } // stops when you hit 'ENTER' 
    std::string line; 
    std::getline(std::cin, line); // consume/stores into line 
    // what was written until hitting 'ENTER' 
} 
관련 문제