まず、ノンブロッキング入力をオンまたはオフにする関数が必要です。
void nonblock(const bool state){
struct termios ttystate;
//get the terminal state
tcgetattr(STDIN_FILENO, &ttystate);
if (state){
//turn off canonical mode
ttystate.c_lflag &= ~ICANON;
//minimum of number input read.
ttystate.c_cc[VMIN] = 1;
}
else{
//turn on canonical mode
ttystate.c_lflag |= ICANON;
}
//set the terminal attributes.
tcsetattr(STDIN_FILENO, TCSANOW, &ttystate);
}
ここで、キーが押されたかどうかをテストおよび確認する関数が必要です。
int keypress(void){
struct timeval tv;
fd_set fds;
tv.tv_sec = 0;
tv.tv_usec = 0;
FD_ZERO(&fds);
FD_SET(STDIN_FILENO, &fds);
select(STDIN_FILENO+1, &fds, NULL, NULL, &tv);
return FD_ISSET(STDIN_FILENO, &fds);
}
2つのことを並行してチェックします。ユーザーがキーを押しましたか、それとも時間がなくなりましたか?指定した秒数後にブール値を変更する関数は次のとおりです。
void SleepForNumberOfSeconds(const int & numberofSeconds,bool & timesUp){
timespec delay = {numberofSeconds,0};
timespec delayrem;
nanosleep(&delay, &delayrem);
timesUp = true;
return;
}
呼び出すことができる主な関数は次のとおりです。
void WaitForTimeoutOrInterrupt(int const& numberofSeconds){
bool timesUp = false;
std::thread t(SleepForNumberOfSeconds, numberofSeconds, std::ref(timesUp));
nonblock(1);
while (!timesUp && !keypress()){
}
if (t.joinable()){
t.detach();
}
nonblock(0);
return;
}
テストするコードは次のとおりです。
コンパイル:
g ++ -std = c ++ 0x -o rand rand.cpp -lpthread
の上:
gcc(Ubuntu / Linaro 4.6.1-9ubuntu3)4.6.1
これは1つの解決策にすぎず、うまくいかない場合があります。
ncursesも調べることを検討してください。