異常與檔案操作

mf1crystal發表於2018-01-24

型別轉換
static_cast 普通資料型別之間的轉換
reinterpret_cast 指標之間的轉換
dynamic_cast 類層次之間的轉換
const_cast 將一個 const常量 轉化為非 const 變數

異常處理機制
什麼是異常?
1)異常是一種程式控制機制,與函式機制獨立和互補
  函式是一種以棧結構展開的上下函式銜接的程式控制系統,異常是另一種控制結構,它依附於棧結構,卻可以同時設定多個異常型別作為網捕條件,從而以型別匹配在棧機制中跳躍回饋.
2)異常設計目的:
棧機制是一種高度節律性控制機制,物件導向程式設計卻要求物件之間有方向、有目的的控制傳動,從一開始,異常就是衝著改變程式控制結構,以適應物件導向程式更有效地工作這個主題,而不是僅為了進行錯誤處理。
異常設計出來之後,卻發現在錯誤處理方面獲得了最大的好處。

異常的基本語法:
拋擲異常的程式段:
void fun()

throw 表示式

捕獲並處理異常的程式段
try{
複合語句

catch(異常型別宣告)
複合語句
catch(型別 (形參))
複合語句
1) 若有異常則通過throw操作建立一個異常物件並拋擲。
2) 將可能丟擲異常的程式段嵌在try塊之中。控制通過正常的順序執行到達try語句,然後執行try塊內的保護段。
3) 如果在保護段執行期間沒有引起異常,那麼跟在try塊後的catch子句就不執行。程式從try塊後跟隨的最後一個catch子句後面的語句繼續執行下去。

異常處理的思想:
1)C++的異常處理機制使得異常的引發和異常的處理不必在同一個函式中,這樣底層的函式可以著重解決具體問題,而不必過多的考慮異常的處理。上層呼叫者可以再適當的位置設計對不同型別異常的處理。
2)異常是專門針對抽象程式設計中的一系列錯誤處理的,C++中不能借助函式機制,因為棧結構的本質是先進後出,依次訪問,無法進行跳躍,但錯誤處理的特徵卻是遇到錯誤資訊就想要轉到若干級之上進行重新嘗試
3)異常超脫於函式機制,決定了其對函式的跨越式回跳。
4)異常跨越函式

棧解旋:
異常被丟擲後,從進入try塊起,到異常被拋擲前,這期間在棧上的構造的所有物件,都會被自動析構。析構的順序與構造的順序相反。這一過程稱為棧的解旋(unwinding)。

異常介面宣告:
1)為了加強程式的可讀性,可以在函式宣告中列出可能丟擲的所有異常型別,例如:
void func() throw (A, B, C , D); //這個函式func()能夠且只能丟擲型別A B C D及其子型別的異常。
2)如果在函式宣告中沒有包含異常介面宣告,則次函式可以拋擲任何型別的異常,例如:
void func();
3)一個不拋擲任何型別異常的函式可以宣告為:
void func() throw();
4) 如果一個函式丟擲了它的異常介面宣告所不允許丟擲的異常,unexpected函式會被呼叫,該函式預設行為呼叫terminate函式中止程式

異常型別和異常變數的生命週期:
1)throw的異常是有型別的,可以使,數字、字串、類物件。
2)throw的異常是有型別的,catch嚴格按照型別進行匹配。
3)注意 異常物件的記憶體模型 。
傳統處理錯誤;
throw int 型別異常
throw字元型別異常
throw類物件型別異常

異常的層次結構(繼承在異常中的應用)
異常是類 – 建立自己的異常類
異常派生
異常中的資料:資料成員
按引用傳遞異常
在異常中使用虛擬函式
案例:設計一個陣列類 MyArray,過載[]操作,
陣列初始化時,對陣列的個數進行有效檢查
index<0 丟擲異常eNegative
index = 0 丟擲異常 eZero
3)index>1000丟擲異常eTooBig
4)index<10 丟擲異常eTooSmall
5)eSize類是以上類的父類,實現有引數構造、並定義virtual void printErr()輸出錯誤

C++的輸入輸出流
I/O流概念和流類庫結構
程式的輸入指的是從輸入檔案將資料傳送給程式,程式的輸出指的是從程式將資料傳送給輸出檔案:
C++輸入輸出包涵一下三個方面的內容:
對形同指定的標準裝置輸入和輸出。即從鍵盤輸入資料,輸出到現實器螢幕,這種輸入輸出成為標準的輸入輸出,簡稱標準I/O;
以外存磁碟檔案為物件輸入和輸出,即從磁碟檔案輸入資料,資料輸出到磁碟檔案,以外存檔案為物件的輸入暑促成為檔案的輸入輸出,簡稱檔案I/O。
對記憶體中指定的空間進行輸入和輸出。通常指定一個字元陣列作為儲存空間(實際上可以利用該空間儲存任何資訊),這種輸入和輸出成為字串的輸入和輸出,簡稱串I/O。

與Iostream類庫有關的標頭檔案
iostream類庫中不同的類的宣告被放在不同的標頭檔案中,使用者在自己的程式中用#include命令包含了有關的標頭檔案就相當於在本程式中宣告瞭所需 要用到的類。可以換 —種說法:標頭檔案是程式與類庫的介面,iostream類庫的介面分別由不同的標頭檔案來實現。常用的有
iostream 包含了對輸入輸出流進行操作所需的基本資訊。
fstream 用於使用者管理的檔案的I/O操作。
strstream 用於字串流I/O。
stdiostream 用於混合使用C和C + +的I/O機制時,例如想將C程式轉變為C++程式。
iomanip 在使用格式化I/O時應包含此標頭檔案。

標準I/O流
標準的輸入流
標準輸入流物件cin,重點掌握的函式
cin.get() //一次只能讀取一個字元 遇到EOF結束
cin.get(一個引數) //讀一個字元
cin.get(三個引數) //可以讀字串
cin.getline()
cin.ignore()
cin.peek()
cin.putback()
標準的輸出流
標準輸出流物件cout
cout.flush()
cout.put()
cout.write()
cout.width()
cout.fill()
cout.setf(標記)

manipulator(操作符、控制符)
flush
endl

C++格式化輸出,C++輸出格式控制
在輸出資料時,為簡便起見,往往不指定輸出的格式,由系統根據資料的型別採取預設的格式,但有時希望資料按指定的格式輸出,如要求以十六進位制或八進位制形式 輸出一個 整數,對輸出的小數只保留兩位小數等。有兩種方法可以達到此目的。
1)使用控制符的方法;
2)使用流物件的有關成員函式。

檔案I/O
檔案流類和檔案流物件
ifstream類,它是從istream類派生的,用來支援從磁碟檔案的輸入。
ofstream類,它是從ostream類派生的,用來支援向磁碟檔案的輸出。
fstream類,它是從iostream類派生的,用來支援對磁碟檔案的輸入輸出。

C++檔案的開啟和關閉
開啟檔案
所謂開啟(open)檔案是一種形象的說法,如同開啟房門就可以進入房間活動一樣。 開啟檔案是指在檔案讀寫之前做必要的準備工作,包括:
1)為檔案流物件和指定的磁碟檔案建立關聯,以便使檔案流流向指定的磁碟檔案。
2)指定檔案的工作方式,如,該檔案是作為輸入檔案還是輸出檔案,是ASCII檔案還是二進位制檔案等。

1) 呼叫檔案流的成員函式open。如
ofstream outfile; //定義ofstream類(輸出檔案流類)物件outfile
outfile.open(“f1.dat”,ios::out); //使檔案流與f1.dat檔案建立關聯
第2行是呼叫輸出檔案流的成員函式open開啟磁碟檔案f1.dat,並指定它為輸出檔案, 檔案流物件outfile將向磁碟檔案f1.dat輸出資料。ios::out是I/O模式的一種,表示以輸出方式開啟一個檔案。或者簡單地說,此時f1.dat是一個輸出檔案,接收從記憶體輸出的資料。

呼叫成員函式open的一般形式為:
檔案流物件.open(磁碟檔名, 輸入輸出方式);
磁碟檔名可以包括路徑,如”c:\new\f1.dat”,如預設路徑,則預設為當前目錄下的檔案。

2) 在定義檔案流物件時指定引數
在宣告檔案流類時定義了帶引數的建構函式,其中包含了開啟磁碟檔案的功能。因此,可以在定義檔案流物件時指定引數,呼叫檔案流類的建構函式來實現開啟檔案的功能。

關閉檔案
在對已開啟的磁碟檔案的讀寫操作完成後,應關閉該檔案。關閉檔案用成員函式close。如
outfile.close( ); //將輸出檔案流所關聯的磁碟檔案關閉
所謂關閉,實際上是解除該磁碟檔案與檔案流的關聯,原來設定的工作方式也失效,這樣,就不能再通過檔案流對該檔案進行輸入或輸出。此時可以將檔案流與其他磁碟檔案建立關聯,通過檔案流對新的檔案進行輸入或輸出。如
outfile.open(“f2.dat”,ios::app|ios::nocreate);
此時檔案流outfile與f2.dat建立關聯,並指定了f2.dat的工作方式。

C++對ASCll檔案的讀寫操作
如果檔案的每一個位元組中均以ASCII程式碼形式存放資料,即一個位元組存放一個字元,這個檔案就是ASCII檔案(或稱字元檔案)。程式可以從ASCII檔案中讀入若干個字元,也可以向它輸出一些字元。
1.用流插入運算子“<<”和流提取運算子“>>”輸入輸出標準型別的資料。“<<”和“ >>”都巳在iostream中被過載為能用於ostream和istream類物件的標準型別的輸入輸出。由於ifstream和 ofstream分別是ostream和istream類的派生類;因此它們從ostream和istream類繼承了公用的過載函式,所以在對磁碟檔案的操作中,可以通過檔案流物件和流插入運算子“<<”及 流提取運算子“>>”實現對磁碟 檔案的讀寫,如同用cin、cout和<<、>>對標準裝置進行讀寫一樣。
2.用檔案流的put、get、geiline等成員函式進行字元的輸入輸出,:用C++流成員函式put輸出單個字元、C++ get()函式讀入一個字元和C++ getline()函式讀入一行字元。

C++對二進位制檔案的讀寫操作:
用成員函式read和write讀寫二進位制檔案
對二進位制檔案的讀寫主要用istream類的成員函式read和write來實現。這兩個成員函式的原型為
istream& read(char *buffer,int len);
ostream& write(const char * buffer,int len);
字元指標buffer指向記憶體中一段儲存空間。len是讀寫的位元組數。呼叫的方式為:
a. write(p1,50);
b. read(p2,30);
上面第一行中的a是輸出檔案流物件,write函式將字元指標p1所給出的地址開始的50個位元組的內容不加轉換地寫到磁碟檔案中。在第二行中,b是輸入文 件流物件,read 函式從b所關聯的磁碟檔案中,讀入30個位元組(或遇EOF結束),存放在字元指標p2所指的一段空間內。

相關文章