2011-08-10 142 views
2

我在LInux/C++中編寫了一個簡單的控制檯應用程序,它接受來自命令行的用戶輸入。我正在線程中使用std::getline(std::cin)/std::cin >> text從stdin停止讀取

10秒鐘後,我想停止接受控制檯輸入並寫入文本消息,然後做其他事情。我正在爲計時器使用單獨的線程。

此方法不起作用,因爲我無法檢查到用戶尚未插入任何文本的時間已過去10秒。

是否有更好的方法來停止應用程序接受文本並轉到另一行?我正在考慮使用settimer和信號編程,但爲了簡單起見,我想從其他線程調用某些東西。

問候

AFG

+2

你能看懂輸入一個新的線程,然後從你的主線程殺死螺紋10秒鐘過去後? – GWW

+1

除了@ GWW的建議之外,您始終可以使用低級別的操作系統設施。在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

哇。看來我有一些有趣的東西可以閱讀。非常感謝。我會嘗試necurse cos似乎也能夠做很多有趣的事情。我會讓你知道的。 –

+0

嗨!我測試了一下延遲。它工作,但它確實需要一些代碼,消耗kbhit()後的緩衝區。我回答如下。非常感謝! –

2

SO問題線程是矯枉過正這一點。在你的輸入循環中使用select()來確定stdin是否準備好讀取。您可以通過調用time()來檢查時間,如果經過了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' 
}