天天看點

2021-03-09為何int類型的變量在不小心輸入字元型之後會造成死循環

為何int類型的變量在不小心輸入字元型之後會造成死循環

在做一個C++小項目時遇到的這個問題,如果輸入的不是整型,而是字元型資料的話,則會跳過cin >> sex;并過不了if判斷一直死循環輸出"輸入有誤,請重新輸入"

cout << "請輸入性别:" << endl;
		cout << "1 --- 男" << endl;
		cout << "2 --- 女" << endl;
		int sex = 0;

		while (true)//用這個循環,直到輸入正确為止,才會退出循環
		{
			//如果輸入的是1或者2,為正确值,将退出循環
			//如果不是則表明輸入錯誤,則需要重新輸入
			cin >> sex;
			//---------------如果這裡sex輸入了+或者字元符号,會進入死循環。-------
			if (sex == 1 || sex == 2)
			{
				abs->personArray[abs->m_Size].m_Sex = sex;
				break;
			}
			else
				cout << "輸入有誤,請重新輸入 " << endl;
		}
           

這裡涉及到一個流狀态的概念

cin或cout 對象包含一個描述流狀态(stream state)的資料成員(從ios_base 類那裡繼承的)。流狀态(被定義為iostate類型,而iostate是一種bitmask類型)由3個ios _base 元素組成: eofbit. badbit 或failbit, 其中每個元素都是一位,可以是1 (設定)或0(清除)。當cin操作到

達檔案末尾時,它将設定eofbit:當cin操作來能讀取到預期的字元時(像前一個例子那樣),它将設定failbit. I/O失敗(如試圖讀取不可通路的檔案或試圖寫入寫保護的磁盤),也可能将failbit設定為1.在一些無法診斷的失敗破壞流時,badbit 元素将被設定(實作沒有必要就哪

些情況下設定failbit,哪些情況下設定badbit達成一緻)。當全部3個狀态位都設定為0時,說明一切順利。程式可以檢查流狀态,并使用這種資訊來決定下一步做什麼。

可以采取clear()和setstate()這兩種方法。

clear();

調用這個函數将使用預設參數0,并将清楚全部的三個狀态位(eofbit、badbit、failbit)

而調用clear(eofbit);時

将狀态設定為efobit,也就是說efobit将被設定,另外兩個狀态位将被清除。

而setstate()方法隻影響其參數中已設定的位。是以,下面的調用将設定eofbit,而不會影響其他位。

setstate(eofbit);

最後的解決方法就是在while循環中加入一個cin.clear(),然後就沒報錯了。這是我目前能想到的方法,可能還有不妥之處,可以評論交流一下。

while (true)//用這個循環,直到輸入正确為止,才會退出循環
		{
			//如果輸入的是1或者2,為正确值,将退出循環
			//如果不是則表明輸入錯誤,則需要重新輸入
			cin.clear();//加入這行就不會死循環了
			cin >> sex;
	
			if (sex == 1 || sex == 2)
			{
				abs->personArray[abs->m_Size].m_Sex = sex;
				break;
			}
			else
				cout << "輸入有誤,請重新輸入 " << endl;
		}
           

繼續閱讀