прекратить чтение со стандартного ввода - PullRequest
2 голосов
/ 10 августа 2011

Я пишу простое консольное приложение на LInux / C ++, которое принимает пользовательский ввод из командной строки. Я использую std::getline( std::cin ) / std::cin >> text в теме.

Через 10 секунд я бы хотел прекратить прием ввода с консоли и написать текстовое сообщение, а затем заняться другими делами Я использую отдельную ветку для таймера.

Этот подход не работает, так как я не могу проверить, что прошло 10 секунд, пока пользователь не вставил какой-либо текст.

Есть ли лучший способ остановить приложение, принимающее текст, и перейти к другому фрагменту строки? Я думал об использовании settimer и программировании сигналов, но для простоты мне хотелось бы что-то вызвать из другого потока.

Привет

AFG

Ответы [ 3 ]

5 голосов
/ 10 августа 2011

Вы можете использовать ncurses или, если вы не хотите, вы можете использовать select, как описано в этом блоге . В основном, вы можете использовать select и указать время ожидания. Если stdin FD установлен, вы можете читать с него безопасно и не будете блокировать. Если вам нужна дополнительная информация о выборе, отметьте this и, конечно, 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);
}

См. Также этот вопрос о Просмотр stdin с использованием pthreads

2 голосов
/ 10 августа 2011

Поток излишним для этого.В вашем цикле ввода используйте select (), чтобы определить, готов ли stdin к чтению.Вы можете проверить время с помощью вызова time () и выйти из цикла, если прошло 10 секунд.

0 голосов
/ 17 августа 2011

Работает хорошо, но необходим небольшой фрагмент кода, который «потребляет» байт.

Ниже использования вашего 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'
 }
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...