C 筆記 io流條件狀態

2021-08-13 17:39:19 字數 2524 閱讀 3158

io流的條件狀態(iostate)一共有4種:

eofbit  已到達檔案尾

failbit  非致命的輸入/輸出錯誤,可挽回

badbit  致命的輸入/輸出錯誤,無法挽回

goodbit  正常,可繼續使用

c++ primer中並沒有從本質上去講這個東西到底是什麼,並不好理解,作者認為應該以以下角度去理解io流的條件狀態(以下僅代表作者個人的理解,並未查證其真實性)

在istream或ostream類中,可能存在這麼乙個變數,它包含3個二進位制位,這個變數表示

乙個stream物件所處於的狀態,可以想象成3個開關,但是

4個狀態為什麼只用3個二進位制位呢?那是因為第4個開關goodbit實則完全取決於前3個開關,前3個開關只要有乙個開啟,則說明io流已經出錯,第4個開關必須關閉,由此,goodbit實際傳達的意思是前3個狀態都是關閉狀態這一資訊,而並不是真正存在goodbit這麼乙個開關。所以這四種狀態可以用這3個二進位制數來表示(4個常量,不要錯誤的認為是變數,下文中使用這四個詞的時候,有時候是表示這個常量的值,有時候表示這個狀態所對應的在io條件狀態變數中的二進位制位置,根據上下文而定):

eofbit:001

failbit:010

badbit:100

goodbit:000

此處還需要注意的乙個點是,這三個開關並不是互斥的,也就是可以同時開啟或開啟其中的任意兩個(從邏輯上不一定符合,比如eofbit和badbit不可能同時發生,但是是可以人為這麼設定的)

每次使用cin或者cout,系統根據結果,設定這個變數中的3個二進位制位的值。

根據以上,就可以很好的理解io流條件狀態涉及到的幾個函式了:

rdstate

():獲取儲存當前狀態的那個變數的值

eof():判斷儲存狀態的變數中eofbit那個二進位制位是否=1(不論其他位的值)

fail

():判斷

儲存狀態的變數中

failbit

那個二進位制位是否=1(不論其他位的值)

bad():判斷

儲存狀態的變數badbit

那個二進位制位是否=1(不論其他位的值)

good

():判斷

儲存狀態的變數

eofbit、

failbit、

badbit的二進位制位是否全部為0

setstate()和clear():

在講這兩個函式前,必須先論述兩個概念:復位和置位。

如果單拿出來乙個,從字面意思上來理解,復位是把乙個開關撥回到初始時候的位置,而置位是把乙個開關根據使用者的想法置於關閉或者開啟的位置,但是這樣理解是完全錯誤的。。。作者作為乙個小白在這個概念上也是糾結的好久才想明白是怎麼回事。。。

復位,實則就是關閉;而置位,實則就是開啟。

setstate()的作用是置位,也就是開啟3個狀態中的1個或者幾個,需要傳入乙個iostate值,然後將傳入值中的3個二進位制位中為1的位置識別,將原io流條件狀態變數中的對應位置設定為1,其他位置不變,說白了就是用狀態變數 |= 傳入的變數。(這裡要有二進位制計算的基礎)。

而clear()的作用則是復位,與setstate形式相同,作用相反,它的本質是用狀態變數 &= 傳入的變數,把傳入的變數中為0的位置在原條件變數中也設定為0,其他位置不變。

舉個c++ primer書上的例子:(作者也是因為一下子想不明白這個例子才進行深入的思考)

cin.clear(cin.rdstate() & ~cin.failbit & ~cin.badbit),書上的解釋是復位failbit和badbit,保持其他標誌位不變

作者一開始想不明白的點在於clear這個函式既然已經指定了關閉這個操作,那麼括號中的引數應該是指定要關閉哪幾個位置,但是引數卻直接給出了最終要設定到的狀態,那麼直接用 io條件狀態變數 = cin.rdstate() & ~cin.failbit & ~cin.badbit進行直接賦值可好?況且還有乙個setstate()函式,如果引數已經給的這麼詳細,那麼clear()和setstate()做的事情不應該是完全一樣嘛——將io狀態條件變數設定成傳入的引數那樣。然而我們不能鑽這個牛角尖。。。它就是這樣,當初的設計者心中的邏輯應該是必須將開啟和關閉分開,用|=和&=這兩個運算子來區分開啟和關閉操作。

那麼這條語句就很清晰了,在引數中傳入乙個變數,將原io條件狀態變數中要關閉的二進位制位,在傳入的這個變數中的對應位置設為0,語句中以原io條件狀態變數為標準,將其failbit和badbit這兩個位置設為0,其他不管,則得到了乙個符合條件的傳入引數。(注:這裡面還有乙個容易迷惑人的地方,那就是failbit和badbit不是變數,而是乙個常量,固定表示 010 和 100 ,不要因為是用cin.引出來的,就錯誤的認為是cin的屬性)。

這裡就不免要吐槽一下。。這個操作就好像開燈和關燈非得要用兩隻手,開燈必須用左手開,關燈要用右手關,setstate和clear的本質區別是其內部到底用|=還是用&=,其實是可以用乙個函式解決的事情,可能c++的設計者覺得這樣在邏輯上更合理,所以使用了這樣一種開關燈用不同手的模式。不過也正是這種模式,才有了下面乙個用起來很方便的函式:

clear的()過載版本,它不需要傳入引數,作用是復位全部3個二進位制位,相當於狀態變數 &= 000。

C IO流條件狀態

測試平台 windows7 vs2010 iostate 流的標誌位 條件狀態 具體如下 標誌位 列舉常量,十進位制分別代表0 1 2 4 16,他們與流狀態無關,標誌位都是常量。判斷標誌位是否有效可以用對應標誌位的成員函式。strm badbit 用來指出流已經奔潰 100 在這裡strm表示一種...

C 語言之標準io庫條件狀態

下面的宣告是錯誤的,指出其錯誤並改正之 ostream print ostream os 答 標準庫型別不允許複製或賦值操作,形參或返回型別不能為流型別。每個 io 類還定義了三個 iostate 型別的常量值,分別表示特定的位模式 1.badbit 標誌著系統級的故障,如無法恢復的讀寫錯誤 2.f...

C 學習筆記之I O流

c 提供的i o流類庫含有兩個平行基類 streambuf 和 ios,所有的流類都是由它們派生出來的。ios類包含四個直接派生類 輸入流類istream,輸出流類ostream,檔案流類fstreambase,串流類strstreambase。i o流類庫最主要的標頭檔案iostream,它支援c...