今天在寫**的時候,遇到了乙個非常奇怪的問題
while
(true)if
(select ==2)
else
}
這段**的本意是想要規範輸入,提高容錯率。但是當我輸入乙個字元比如』a』的時候,while迴圈中的cin語句將會被跳過,進入無限的死迴圈。上網查閱了很多資料,發現了問題所在
msdn上cin的定義如下
看不懂也沒關係,以下為它的翻譯
cin該物件控制從標準輸入中以位元組流形式進行的提取。構造物件後,呼叫cin.tie()返回&cout。
因為cin是乙個輸入流,當要求給乙個整型賦值的時候,輸入的型別可能與該整型不匹配,導致快取溢位。如果輸入的過多了,那麼,那些輸入除了一部分賦值給變數以外還有剩餘的位元組,這些剩餘的輸入將殘留在輸入快取中,就會導致在下面需要輸入的時候不再接受輸入,而直接從快取中獲得。
所以,出現這個問題後可行的解決方法如下:
一、更換被賦值整型的資料型別
這裡使用string類來接收輸入,需要先包含標頭檔案string
string型別是一種順序表的結構,元素是char型別的字元,這個型別可以根據輸入自動分配所佔記憶體空間的大小,string的最大容量取決於機器本身的限制或者字串所在位置連續記憶體的大小(一般來說絕對夠你用的了,除非你在這個輸入位置輸進去了一篇幾萬字的學術**。)
當採用了string型別來接收資料流的時候,媽媽再也不用擔心我會快取溢位了
(>-
二、使用cin物件中自帶的函式清空快取區
萬一,我說的是萬一,真的有人想不辭辛勞地輸入一篇萬字長文來挑戰你**的健壯性,這個時候該怎麼辦呢?那當然是把他的頭錘爆 那當然是換一種方法從根本上解決問題啊~
cin這個類提供了方法來對快取區進行清空,以下為方法詳解
當cin在接收到錯誤的輸入的時候,會設定狀態位good。如果good位不為1,則cin不接受輸入,直接跳過。如果下次輸入前狀態位沒有改變那麼即使清除了緩衝區資料流也無法輸入。所以清除緩衝區之前必須要重置cin的狀態位。
在這裡我們採用cin類中的clear()函式,具體語法如下
cin.
clear()
;//如果在前面沒有宣告命名空間的話,要這樣寫:
std::cin.
clear()
;
好了,重置了cin的狀態位,下面需要進行緩衝區的清理,這裡使用的是cin類中的ignore函式(也有使用sync()函式的,但由於程式執行時並不總是知道外部輸入的進度,很難控制是不是全部清除輸入緩衝區的內容。通常我們有可能只是希望放棄輸入緩衝區中的一部分,而不是全部)。語法如下:
//清除輸入緩衝區的當前行
cin.
ignore
(numeric_limits<:streamsize>
::max()
,'\n');
//清除輸入緩衝區裡所有內容
cin.
ignore
(numeric_limits<:streamsize>
::max()
);//清除乙個字元
cin.
ignore
()
好了,清除過後,你的**就像掌控了兄♂貴♂之♂力一樣健壯,再也不怕有熊孩子搞崩你的程式 while迴圈中將cin輸入作為條件問題 擴充套件
先看一段 vector int vecnum int num 0 while cin num vecnum.push back num cin num 這是乙個簡單的 但是這裡會有乙個問題,就是 cin num 位於迴圈外的輸入這行 無法輸入任何數值。原因是什麼呢?我們知道在迴圈中,我們想要結束迴圈...
死迴圈中的cin
在編寫程式時,遇到了乙個致命的問題,原本是想使用cin輸入乙個int型的數值,但是錯誤的輸入了char或者string型,導致程式進入死迴圈。類似程式如下 include using namespace std int main while i 0 return 0 定義了乙個int型的 i 但是當...
C 運用cin來控制while迴圈
c 中有時需要用迴圈輸入數字,而將非數字輸入設定為乙個錯誤條件,如 while cin x y 我們知道,cin時istream類的乙個物件,抽取運算子 被設計成使得cin x也是乙個istream物件,類運算子是使用函式實現的。使用cin x時,程式將呼叫乙個函式,該函式返回乙個istream值。...