停止从stdin读取

时间:2011-08-10 14:17:49

标签: c++ timer console-application stdin

我在LInux / C ++中编写一个简单的控制台应用程序,它接受来自命令行的用户输入。我在一个帖子中使用std::getline( std::cin ) / std::cin >> text

10秒后,我想停止接受控制台输入并写一条短信然后做其他事情。我正在为计时器使用一个单独的线程。

这种方法不起作用,因为在用户未插入任何文本之前我无法检查是否已经过了10秒。

有没有更好的方法来阻止应用程序接受文本并转到另一行?我正在考虑使用settimer并发出编程信号,但为了简单起见,我想从不同的线程调用一些东西。

此致

AFG

3 个答案:

答案 0 :(得分:5)

您可以使用ncurses,或者如果您不想,可以按照此blog post中的说明使用select。基本上,您可以使用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

上的此问题

答案 1 :(得分:2)

一个线程对此有点过分。在输入循环中使用select()来确定stdin是否已准备好进行读取。您可以通过调用time()来检查时间,如果已经过了10秒,则退出循环。

答案 2 :(得分: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'
 }