2017-01-09 349 views
1

有沒有方法可以調用getline(),如果沒有給出輸入,不要阻止和等待?如何使用getline而不阻塞輸入?

我有以下代碼:

while(true){ 
    if(recv(sd, tBuffer, sizeof(tBuffer), MSG_PEEK | MSG_DONTWAIT) > 0) break; 
    getline(cin,send); 
} 

我想等待輸入,但如果我在sd插口接收的一些數據,我想停下等待數據並退出while。我現在的代碼只是在getline()的第一次迭代。我想評估getline(),如果沒有可用輸入,請返回if

這可能嗎?

PS:我嘗試了cin.peek(),但也阻止了輸入。

+1

要回答問題:是的,這是可能的。至少在Linux上。 –

+0

我使用Ubuntu ..我怎麼可能?你能給我一些鏈接或向我解釋? – Darius

+1

簡短的回答是:1)使用低級I/O,而不是'getline'。 2)使用'select'。 –

回答

3

您應該能夠通過設置標準輸入非阻塞模式,文件描述符0做到這一點:現在

int flags = fcntl(0, F_GETFL, 0); 
fcntl(0, F_SETFL, flags | O_NONBLOCK); 

,如果沒有輸入可用,底層read()系統調用將返回0, std::cin會認爲這是文件結尾,並在std::cin上設置eof()

當你想再次從標準輸入讀取,只需clear()流的狀態。

這裏唯一複雜的因素是,這使得難以檢測std::cin上的真實文件結束條件。當標準輸入是一個交互式終端時,沒什麼問題;但如果標準輸入可以是一個文件,這將是一個問題。

在這種情況下,你的唯一現實的選擇是完全放棄std::cin,把非阻塞模式文件描述符0,poll()select()它,以確定何時有東西可以讀,然後read()它。

雖然你也可以使用poll()select()std::cin,這會變得複雜,因爲你需要明確檢查是否有在std::cinstreambuf已經緩衝的任何東西,因爲那會,很顯然,搶佔任何形式的poll()select()檢查;但是通過嘗試從std::cin中讀取某些內容,仍然有讀取緩衝數據的風險,然後嘗試從現在處於非阻止模式的基礎文件描述符中嘗試read(),這會導致文件結束狀態不正確。總結一下:你需要投入一些額外的時間來閱讀和理解文件流和流緩衝區如何工作;以及文件描述符如何實際工作以及非阻塞模式如何工作;以便找出您需要使用的正確邏輯。

哦,如果你堅持要與std::cin非阻塞路線,並getline(),你有沒有簡單的方法來確定是否由getline()返回的字符串結束,因爲getline()實際上從標準輸入讀取一個新行,或者達到了文件狀態的過早假結束,而不是整個輸入行已被實際讀取。

因此,在非阻塞模式和std::cin下,您將幾乎被迫使用read()而不是getline()