C++ cin不同狀態(tài)詳細(xì)講解
前言
在C++中std::cin>>x,這是一條從std::cin中讀取輸入到x中的語(yǔ)句。而>>操作數(shù)是從標(biāo)準(zhǔn)輸入中讀取一個(gè)字符串,并把它保存在x對(duì)象中。
讀取操作包括:
1、從輸入流緩沖區(qū)緩存的輸入字節(jié)快中提取對(duì)應(yīng)于右操作數(shù)數(shù)據(jù)類型的字節(jié)字塊。如果緩存為空,則等待輸入設(shè)備提交字節(jié)塊。
2、再將字節(jié)子塊轉(zhuǎn)換為右操作數(shù)對(duì)應(yīng)類型的編碼存放在右操作數(shù)中。
對(duì)于cin之類的流對(duì)象有g(shù)ood和not good兩種狀態(tài),cin>>x讀取數(shù)據(jù)成功時(shí),會(huì)返回good狀態(tài);cin>>x讀取數(shù)據(jù)失敗時(shí),會(huì)返回not goot狀態(tài)。注意good狀態(tài)的流才能讀/寫流緩沖區(qū)的數(shù)據(jù);not good狀態(tài)的流會(huì)忽略即不執(zhí)行讀/寫操作。
反過(guò)來(lái),流的讀/寫操作也會(huì)影響流的狀態(tài),成功的讀/寫操作會(huì)使流保持good狀態(tài);失敗的讀/寫操作會(huì)設(shè)置流的狀態(tài)變量的錯(cuò)誤標(biāo)志,表示流在讀/寫操作后處于某種錯(cuò)誤(not good)的狀態(tài)。
流的錯(cuò)誤狀態(tài)可以分為failbit、eofbit和badbit三種錯(cuò)誤狀態(tài)。
常量 | failbit | eofbit | badbit | 轉(zhuǎn)為10進(jìn)制 |
ios::failbit | 1 | 0 | 0 | 4 |
ios::eofbit | 0 | 1 | 0 | 2 |
ios::badbit | 0 | 0 | 1 | 1 |
ios::goodbit | 0 | 0 | 0 | 0 |
基本讀取狀態(tài)的函數(shù)rdstate(),其余狀態(tài)讀取函數(shù)是good()、fail()、eof()、bad()等。
三種錯(cuò)誤狀態(tài):
- fail():讀取值與期望接受值的類型不兼容即錯(cuò)誤格式,狀態(tài)變量的failbit被置位,fail()為真,進(jìn)入fail狀態(tài)。這種錯(cuò)誤是可恢復(fù)的,可重新設(shè)置流為good狀態(tài),繼續(xù)讀取數(shù)據(jù),但需要丟棄前面輸入的數(shù)據(jù)。
- eof():讀取值為文件結(jié)束標(biāo)記eof,此時(shí)cin會(huì)記錄該標(biāo)記,狀態(tài)變量的eodbit和failbit被同時(shí)置位,eof()為真,進(jìn)入eof狀態(tài)。
- bad():由于輸入設(shè)備故障導(dǎo)致的數(shù)據(jù)丟失,狀態(tài)變量的badbit和failbit被置位,bad()為真,進(jìn)入bad狀態(tài),這種錯(cuò)誤不可恢復(fù),流對(duì)象將不可再用。
注意:當(dāng)流處于錯(cuò)誤狀態(tài)時(shí),狀態(tài)變量的failbit總是被置位(true),因此有時(shí)候也可以將表達(dá)式!fail()作為判斷流是否為good的條件來(lái)使用。
介紹一下cin的三個(gè)函數(shù):
- cin.clear():是用來(lái)更改cin的狀態(tài)標(biāo)識(shí)符的,將cin的所有狀態(tài)值重設(shè)為有效值。
- cin.sync():是用來(lái)清除緩存區(qū)的數(shù)據(jù)流的。
- cin.ignore(n,ch):從輸入流中提取字符,提取的字符被忽略,不被使用,每拋棄一個(gè)字符,它都要計(jì)數(shù)和比較字符,如果計(jì)數(shù)值達(dá)到n或者被拋棄的字符是ch,則cin.ignore()函數(shù)執(zhí)行終止,否則繼續(xù)等待。
注意:當(dāng)cin出錯(cuò)時(shí),先要用cin.clear()重置cin狀態(tài)值后,后面兩個(gè)函數(shù)才能起到作用,但cin.ignore()要比cin.sync()更加靈活。
一、下面給幾個(gè)案例
#include <iostream> using namespace std; int main() { int x; cout << "請(qǐng)輸入一個(gè)整數(shù):"; cin >> x; cout << " cin.good(): " << cin.good() << endl; cout << " cin.rdstste(): " << cin.rdstate() << endl; cout << " cin.fail(): " << cin.fail() << endl; cout << " cin.eof(): " << cin.eof() << endl; cout << " cin.bad(): " << cin.bad() << endl; return 0; }
1、輸入正確且類型匹配的情況:
2、輸入一個(gè)字符時(shí),類型不匹配的情況:
3、以eof結(jié)尾:
(在Windows下是輸入Ctrl+z,Linux下是輸入Ctrl+d,都要進(jìn)行換行后再輸入)
二、當(dāng)我們對(duì)這個(gè)程序進(jìn)行改進(jìn)后
#include <iostream> using namespace std; int main() { int x; int sum = 0; cout << "請(qǐng)輸入一串整數(shù):"; while (cin>>x) { sum += x; } cout <<"sum = " << sum << endl; cout << " cin.good(): " << cin.good() << endl; cout << " cin.rdstste(): " << cin.rdstate() << endl; cout << " cin.fail(): " << cin.fail() << endl; cout << " cin.eof(): " << cin.eof() << endl; cout << " cin.bad(): " << cin.bad() << endl; cout << endl; cin.clear(); char y; cin >> y; int z; cin>>z; cout <<"y = " << y << endl; cout <<"z = " << z << endl; cout << " cin.good(): " << cin.good() << endl; cout << " cin.rdstste(): " << cin.rdstate() << endl; cout << " cin.fail(): " << cin.fail() << endl; cout << " cin.eof(): " << cin.eof() << endl; cout << " cin.bad(): " << cin.bad() << endl; return 0; }
在代碼中用了一個(gè)循環(huán)輸入,提示輸入一串整數(shù),在前面四個(gè)數(shù)都是整數(shù)的情況下,而第五個(gè)數(shù)輸入了一個(gè)字符,后面兩個(gè)數(shù)仍然是整數(shù),但是當(dāng)執(zhí)行時(shí),sum的值卻是14,也就是說(shuō)x成功保存了四個(gè)數(shù),這就是上面說(shuō)的fail錯(cuò)誤狀態(tài),x不能再讀出流緩沖區(qū)的數(shù)據(jù),這是因?yàn)榈谖鍌€(gè)數(shù)是字符類型的,與x類型不匹配,再用clear()函數(shù)重置cin狀態(tài),由于y是char類型,z是int類型,后面的cin>>y和cin>>z又可以繼續(xù)讀出流緩沖區(qū)里的數(shù)據(jù)。
#include <iostream> using namespace std; int main() { int x; int sum = 0; cout << "請(qǐng)輸入一串整數(shù):"; while (cin>>x) { sum += x; } cout <<"sum = " << sum << endl; cout << " cin.good(): " << cin.good() << endl; cout << " cin.rdstste(): " << cin.rdstate() << endl; cout << " cin.fail(): " << cin.fail() << endl; cout << " cin.eof(): " << cin.eof() << endl; cout << " cin.bad(): " << cin.bad() << endl; cout << endl; cin.clear(); cout << " clear后:" << endl; cout << " cin.good(): " << cin.good() << endl; cout << " cin.rdstste(): " << cin.rdstate() << endl; cout << " cin.fail(): " << cin.fail() << endl; cout << " cin.eof(): " << cin.eof() << endl; cout << " cin.bad(): " << cin.bad() << endl; cout << endl; int y; cin >> y; int z; cin>>z; cout <<"y = " << y << endl; cout <<"z = " << z << endl; cout << " cin.good(): " << cin.good() << endl; cout << " cin.rdstste(): " << cin.rdstate() << endl; cout << " cin.fail(): " << cin.fail() << endl; cout << " cin.eof(): " << cin.eof() << endl; cout << " cin.bad(): " << cin.bad() << endl; return 0; }
這里只是將上面的char y改成了int y,可以看運(yùn)行結(jié)果的不同,此時(shí)的cin.clear()雖然起作用,但由于流緩沖區(qū)里還有數(shù)據(jù),y和z會(huì)嘗試去讀取里面的數(shù)據(jù),而y的類型不匹配再次讓流的狀態(tài)變成fail狀態(tài),y和z就都不能讀取數(shù)據(jù)了,輸入y和z的值是程序自動(dòng)初始化的。
#include <iostream> using namespace std; int main() { int x; int sum = 0; cout << "請(qǐng)輸入一串整數(shù):"; while (cin>>x) { sum += x; } cout <<"sum = " << sum << endl; cout << " cin.good(): " << cin.good() << endl; cout << " cin.rdstste(): " << cin.rdstate() << endl; cout << " cin.fail(): " << cin.fail() << endl; cout << " cin.eof(): " << cin.eof() << endl; cout << " cin.bad(): " << cin.bad() << endl; cout << endl; cin.clear(); cin.sync(); int y; cin >> y; int z; cin>>z; cout <<"y = " << y << endl; cout <<"z = " << z << endl; cout << " cin.good(): " << cin.good() << endl; cout << " cin.rdstste(): " << cin.rdstate() << endl; cout << " cin.fail(): " << cin.fail() << endl; cout << " cin.eof(): " << cin.eof() << endl; cout << " cin.bad(): " << cin.bad() << endl; return 0; }
當(dāng)在cin.clear()后面加上cin.sync()函數(shù)后,sync()函數(shù)會(huì)清除緩存區(qū)的數(shù)據(jù),此時(shí)緩存區(qū)里面就沒(méi)有數(shù)據(jù)了,對(duì)于cin>>y和cin>>z,就需要我們自己輸入數(shù)據(jù)了。
總結(jié)
對(duì)于cin的錯(cuò)誤狀態(tài),我們可以用cin的其他幾個(gè)函數(shù)將其恢復(fù)成good狀態(tài),cin.clear()一般和cin.sync()一起使用。
參考書籍:Accelerated C++和Cpp_Primer_5
到此這篇關(guān)于C++ cin不同狀態(tài)詳細(xì)講解的文章就介紹到這了,更多相關(guān)C++ cin內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
C語(yǔ)言中結(jié)構(gòu)體與內(nèi)存對(duì)齊實(shí)例解析
C語(yǔ)言結(jié)構(gòu)體對(duì)齊也是老生常談的話題了,基本上是面試題的必考題,這篇文章主要給大家介紹了關(guān)于C語(yǔ)言中結(jié)構(gòu)體與內(nèi)存對(duì)齊的相關(guān)資料,需要的朋友可以參考下2021-07-07STL區(qū)間成員函數(shù)及區(qū)間算法總結(jié)
這篇文章主要匯總介紹了STL區(qū)間成員函數(shù)及區(qū)間算法,有需要的小伙伴可以參考下。2015-07-07如何利用最簡(jiǎn)單的C語(yǔ)言實(shí)現(xiàn)AI五子棋
這篇文章主要給大家介紹了關(guān)于如何利用最簡(jiǎn)單的C語(yǔ)言實(shí)現(xiàn)AI五子棋的相關(guān)資料,包含了一些五子棋常見的功能,文中也通過(guò)詳細(xì)的實(shí)例代碼和圖片介紹的非常詳細(xì),需要的朋友可以參考下2021-07-07C語(yǔ)言實(shí)現(xiàn)俄羅斯方塊的六種模式詳程建議收藏
遲早一定會(huì)掛掉的俄羅斯方塊,為什么至今仍是世界游戲之王?它是怎么編寫的?本文將給大家詳細(xì)介紹六種模式的實(shí)現(xiàn),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值2022-02-02C語(yǔ)言 數(shù)據(jù)結(jié)構(gòu)之鏈表實(shí)現(xiàn)代碼
這篇文章主要介紹了C語(yǔ)言 數(shù)據(jù)結(jié)構(gòu)之鏈表實(shí)現(xiàn)代碼的相關(guān)資料,需要的朋友可以參考下2016-10-10