cin 在 Ctrl+Z 或 Ctrl+D 後無法獲取輸入

自己寫了一個數字計數的小程序,我先輸入一堆數字,輸入完成後再輸入一個要搜索的數字
但是我輸入完數字集合按下ctrl+d後,程序就直接結束了,根本不會在第二在輸入的地方停留,我在網上查了查,發現很多人遇到了這個問題
首先看到的解決方法是,輸入完成後加一句

cin.clear();

但是我用了沒有效果,又看到可以再加一句

cin.sync();

用了以後同樣沒有效果,前一個的作用是將錯誤狀態更改爲有效狀態,後一個是清除緩衝區中的未讀信息,按說這樣是可以的了,而且我通過讀cin.rdstate(),可可以看到恢復爲0,但是問題依舊沒有解決,繼續查找資料,又找到讓加下面兩句

cin.clear();
clearerr(stdin);

然後問題就解決了

經過查找以後發現上面的解決辦法是可以解決windos平臺的代碼的,而我是在Linux下,所以必須用下面的辦法
原因如下:
cin方法檢測到EOF時,將設置cin對象中一個指示EOF條件的標記。設置這個標記後,cin將不讀取輸入再次調用cin也不管用…cin.clear()方法可能清除EOF標記,使輸入繼續進行。不過要記住的是,在有些系統中,按crl+z/ctrl+d實際上將結束輸入和輸出,而 cin.clear()將無法恢復輸入和輸出。
而爲何添加同樣的代碼, Windows 上就可以,Mac 上就不可以呢?

輸入緩衝是行緩衝。當從鍵盤上輸入一串字符並按回車後,這些字符會首先被送到輸入緩衝區中存儲。每當按下回車鍵後,cin.get() 就會檢測輸入緩衝區中是否有了可讀的數據。cin.get() 還會對鍵盤上是否有作爲流結束標誌的 Ctrl+Z 或者 Ctrl+D 鍵按下作出檢查,其檢查的方式有兩種:阻塞式以及非阻塞式。

阻塞式檢查方式指的是只有在回車鍵按下之後纔對此前是否有 Ctrl+Z 組合鍵按下進行檢查,非阻塞式樣指的是按下 Ctrl+D 之後立即響應的方式。如果在按 Ctrl+D 之前已經從鍵盤輸入了字符,則 Ctrl+D的作用就相當於回車,即把這些字符送到輸入緩衝區供讀取使用,此時Ctrl+D不再起流結束符的作用。如果按 Ctrl+D 之前沒有任何鍵盤輸入,則 Ctrl+D 就是流結束的信號。

Windows系統中一般採用阻塞式檢查 Ctrl+Z、Unix/Linux系統下一般採用非阻塞式的檢查 Ctrl+D。 阻塞式有一個特點:只有按下回車之後纔有可能檢測在此之前是否有Ctrl+Z按下。還有一個特點就是:如果輸入緩衝區中有可讀的數據則不會檢測 Ctrl+Z(因爲有要讀的數據,還不能認爲到了流的末尾)。還有一點需要知道:Ctrl+Z產生的不是一個普通的ASCII碼值,也就是說它產生的不是 一個字符,所以不會跟其它從鍵盤上輸入的字符一樣能夠存放在輸入緩衝區。

而clearerr的作用是什麼呢:
參照官方文檔:地址
簡單地說就是它可以重置流的狀態,其參數就是需要重置的流。而 cin.clear() 並不能保證可以重置流,
clear官方文檔:地址

發佈了123 篇原創文章 · 獲贊 616 · 訪問量 35萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章