第九章流類庫和輸入輸出54
《第九章流類庫和輸入輸出54》由會員分享,可在線閱讀,更多相關《第九章流類庫和輸入輸出54(83頁珍藏版)》請在裝配圖網上搜索。
1、第九章第九章 流類庫和輸入流類庫和輸入/ /輸出輸出本章的最主要目的就是把對象保存到磁盤文件中并從本章的最主要目的就是把對象保存到磁盤文件中并從磁盤文件重建對象。當然磁盤文件重建對象。當然C+可完成更多的任務??赏瓿筛嗟娜蝿铡+語言中并沒有輸入語言中并沒有輸入/輸出語句,而是在標準庫輸出語句,而是在標準庫里包含了一個里包含了一個I/O流類庫,它與標準模板庫同為流類庫,它與標準模板庫同為C+標標準庫中最重要的組成部分。數據從一個對象到另一個對準庫中最重要的組成部分。數據從一個對象到另一個對象的傳送被抽象為象的傳送被抽象為“流流”。數據的輸入。數據的輸入/輸出就是通過輸出就是通過輸入輸入/輸出
2、流來實現的。輸出流來實現的。 流是一種抽象的概念,負責在數據的產生者和數據流是一種抽象的概念,負責在數據的產生者和數據的使用者之間建立聯系,并管理數據的流動。的使用者之間建立聯系,并管理數據的流動。 第九章第九章 流類庫和輸入流類庫和輸入/ /輸出輸出9.1 C+的基本流類體系的基本流類體系 9.3 標準設備的輸入標準設備的輸入/輸出輸出 9.2 輸入輸出的格式控制輸入輸出的格式控制 9.4 文件的輸入與輸出文件的輸入與輸出 9.7 圖書館流通管理系統設計圖書館流通管理系統設計 輸出輸出/輸入流的應用輸入流的應用 9.5 字符串流(內存流)字符串流(內存流) 9.6 MFC中的文件處理中的文件
3、處理 9.1 C+的基本流類體系的基本流類體系整個流類體系是一個派生類體系。整個流類體系是一個派生類體系。按按ANSI C+標準,類標準,類ios是抽象類,它的析構函數是虛函數,它是抽象類,它的析構函數是虛函數,它的構造函數為保護的,作為所有基本流類的基類。的構造函數為保護的,作為所有基本流類的基類。VC+中有一個構造函數中有一個構造函數ios (streambuf*)為公有,與為公有,與ANSI C+不同。不同。圖圖9.1 輸入輸入/輸出流類派生體系輸出流類派生體系iosstreambufistreamostreamistream_withassigniostreamostream_with
4、assigniostream_withassign指針指針9.1 C+的基本流類體系的基本流類體系iostreamfstreamstrstreamstdiostreamiosistreamifstrstreamistream_withassignifstreamstreambuffilebufstrstreambufstdiobufiostream_initostreamofstreamostream_withassign ostrstream圖圖9.2 輸入輸入/輸出流類層次輸出流類層次streambuf是一個獨立的是一個獨立的類,只是類,只是ios有一個保護訪有一個保護訪問限制的指針指向它
5、。問限制的指針指向它。streambuf的作用是管理的作用是管理一個流的緩沖區(qū)。一個流的緩沖區(qū)。ios提供了對流進行格式化提供了對流進行格式化輸入輸出和錯誤處理的成輸入輸出和錯誤處理的成員函數。所有派生都是公員函數。所有派生都是公有派生。有派生。istream類提供完類提供完成成提?。ㄝ斎耄┨崛。ㄝ斎耄┎僮鞯某刹僮鞯某蓡T函數,而員函數,而ostream類提供類提供完成完成插入(輸出)插入(輸出)操作的操作的成員函數。成員函數。iostream類是類是前兩者的組合。前兩者的組合。9.1 C+的基本流類體系的基本流類體系在流類庫中,最重要的兩部分功能為在流類庫中,最重要的兩部分功能為標準輸入標準輸
6、入/ /輸出輸出(standard input/outputstandard input/output)和)和文件處理文件處理。 在在C+C+的流類庫中定義了四個全局流對象:的流類庫中定義了四個全局流對象:cincin,coutcout,cerrcerr和和clogclog??梢酝瓿扇藱C交互的功能??梢酝瓿扇藱C交互的功能。 cin標準輸入流對象,鍵盤為其對應的標準設備。標準輸入流對象,鍵盤為其對應的標準設備。 cout標準輸出流對象,顯示器為標準設備。標準輸出流對象,顯示器為標準設備。 cerr和和clog標準錯誤輸出流,輸出設備是顯示器。標準錯誤輸出流,輸出設備是顯示器。 其中其中cin、c
7、out和和clog是帶緩沖區(qū)的,緩沖區(qū)由是帶緩沖區(qū)的,緩沖區(qū)由streambuf類對象來管理。而類對象來管理。而cerr為非緩沖區(qū)流,一旦為非緩沖區(qū)流,一旦錯誤發(fā)生立即顯示。錯誤發(fā)生立即顯示。 要使用這四個功能,必須包含要使用這四個功能,必須包含文件。文件。 9.1 C+的基本流類體系的基本流類體系提取運算符提取運算符“”(stream_extraction operator)和和插入運算符插入運算符“”(stream_insertion operator),),執(zhí)行輸入執(zhí)行輸入/輸出操作。輸出操作。 “提取提取”的含義是指輸入操作,可看作從流中提的含義是指輸入操作,可看作從流中提取一個字符序
8、列。取一個字符序列。 “插入插入”的含義是指輸出操作,可看作向流中插的含義是指輸出操作,可看作向流中插入一個字符序列。入一個字符序列。 文件處理完成永久保存的功能。在文件處理完成永久保存的功能。在VC+VC+的的MFCMFC編編程中采用了序列化(程中采用了序列化(SerializationSerialization)。)。 9.2 輸入輸出的格式控制輸入輸出的格式控制enum skipws=0 x0001,/跳過輸入中的空白字符跳過輸入中的空白字符 left=0 x0002, /輸出左對齊輸出左對齊 right=0 x0004,/輸出右對齊輸出右對齊 internal=0 x0008,/在輸出
9、符號或數制字符后填充在輸出符號或數制字符后填充 dec=0 x0010,/在輸入輸出時將數據按十進制處理在輸入輸出時將數據按十進制處理 oct=0 x0020,/在輸入輸出時將數據按八進制處理在輸入輸出時將數據按八進制處理 hex=0 x0040,/在輸入輸出時將數據按十六進制處理在輸入輸出時將數據按十六進制處理 showbase=0 x0080,/在輸出時帶有表示數制基的字符在輸出時帶有表示數制基的字符 C+在類在類ios中提供格式化輸入輸出。這些格式中提供格式化輸入輸出。這些格式是對所有文本方式的輸入輸出流均適用。格式是對所有文本方式的輸入輸出流均適用。格式控制符定義為公有的無名的枚舉類型
10、:控制符定義為公有的無名的枚舉類型:9.2 輸入輸出的格式控制輸入輸出的格式控制showpoint=0 x0100, /輸出浮點數時輸出浮點數時,必定帶小數點必定帶小數點 uppercase=0 x0200,/輸出十六進制輸出十六進制,用大寫用大寫 showpos=0 x0400,/輸出正數時輸出正數時,加加”+”號號 scientific=0 x0800,/科學數方式輸出浮點數科學數方式輸出浮點數 fixed=0 x1000,/定點數方式輸出實數定點數方式輸出實數 unitbuf=0 x2000,/插入后插入后,立即刷新流立即刷新流 stdio=0 x4000 /插入后插入后,立即刷新立即刷
11、新stdout和和stderr該枚舉量說明中該枚舉量說明中每一個枚舉量實際對應兩字節(jié)數據(每一個枚舉量實際對應兩字節(jié)數據(16位)中位)中的一個位的一個位,所以可以同時采用幾個格式控制,只要把,所以可以同時采用幾個格式控制,只要把對應位置對應位置1即可,這樣既方便又節(jié)約內存。取多種控制時,用或即可,這樣既方便又節(jié)約內存。取多種控制時,用或“|”運運算符來合成,合成為一個長整型數,在算符來合成,合成為一個長整型數,在ios中為:中為:protected:long x_flags;9.2 輸入輸出的格式控制輸入輸出的格式控制類類ios中還設置了三個中還設置了三個輸入輸出流格式控制標志輸入輸出流格式
12、控制標志:protected: int x_precision; /標志浮點數精度標志浮點數精度,缺省為缺省為6位位 int x_width; /輸出域寬輸出域寬,缺省域寬為缺省域寬為0, /重設域寬只對其后第一輸出項有效重設域寬只對其后第一輸出項有效,如域寬不足如域寬不足,則不受限制則不受限制 char x_fill; /標志域寬有富余時填入的字符標志域寬有富余時填入的字符點擊訪問點擊訪問x_flags的重載函數的重載函數定義定義點擊訪問點擊訪問格式控制標志相關接口函數格式控制標志相關接口函數【例【例9.1】整型數輸出。整型數輸出。【例【例9.2】浮點數輸出。浮點數輸出。9.2 輸入輸出的格
13、式控制輸入輸出的格式控制程序執(zhí)行后輸出:程序執(zhí)行后輸出:缺省域寬為缺省域寬為:0位位缺省精度為缺省精度為:6位位缺省表達方式缺省表達方式:31.4159科學數表達方式科學數表達方式:3.141593e+001定點表達方式定點表達方式:31.4159279位科學數表達方式位科學數表達方式:3.141592654e+001 流操作子(流操作子(setiosflags stream manipulator)可代替流格式控制成員函數:可代替流格式控制成員函數:點擊點擊查閱流操作子查閱流操作子9.3 標準設備的輸入標準設備的輸入/ /輸出輸出標準設備輸入是最不安全的,注意以下幾點,可以標準設備輸入是最不
14、安全的,注意以下幾點,可以避免錯誤:避免錯誤:1. cin為為緩沖流緩沖流。鍵盤輸入的數據保存在緩沖區(qū)中,。鍵盤輸入的數據保存在緩沖區(qū)中,當要提取時,是從緩沖區(qū)中拿。如果一次輸入過當要提取時,是從緩沖區(qū)中拿。如果一次輸入過多,會留在那兒慢慢用,如果輸入錯了,必須在多,會留在那兒慢慢用,如果輸入錯了,必須在回車之前修改回車之前修改,如果回車鍵按下就無法挽回了。,如果回車鍵按下就無法挽回了。只有把輸入緩沖區(qū)中的數據取完后,才要求輸入只有把輸入緩沖區(qū)中的數據取完后,才要求輸入新的數據。不可能用刷新來清除緩沖區(qū),所以新的數據。不可能用刷新來清除緩沖區(qū),所以不不能輸錯,也不能多輸能輸錯,也不能多輸!9.
15、3 標準設備的輸入標準設備的輸入/ /輸出輸出2. 輸入的數據類型必須與要提取的數據類型一致輸入的數據類型必須與要提取的數據類型一致,否則出錯。出錯只是在流的狀態(tài)字否則出錯。出錯只是在流的狀態(tài)字state(枚舉(枚舉類型類型io_state)中對應位置位(置)中對應位置位(置1),程序繼),程序繼續(xù)。所以要提高健壯性,就必須在編程中續(xù)。所以要提高健壯性,就必須在編程中加入對加入對狀態(tài)字狀態(tài)字state的判斷的判斷。3. 空格和回車都可以作為數據之間的分格符,所以空格和回車都可以作為數據之間的分格符,所以多個數據可以在一行輸入,也可以分行輸入。但多個數據可以在一行輸入,也可以分行輸入。但如果是如
16、果是字符型和字符串字符型和字符串,則,則空格空格(ASCII碼為碼為32)無法用無法用cin輸入輸入,字符串中也不能有空格。回車,字符串中也不能有空格?;剀嚪矡o法讀入。符也無法讀入。狀態(tài)字狀態(tài)字state為為整型,其的各位在整型,其的各位在ios中說明:中說明: enum ios_state goodbit=0 x00, /流正常流正常 eofbit=0 x01, /輸入流結束忽略后繼提取操作;或文件結束已無數據可取輸入流結束忽略后繼提取操作;或文件結束已無數據可取 failbit=0 x02, /最近的最近的I/O操作失敗操作失敗,流可恢復流可恢復 badbit=0 x04, /最近的最近
17、的I/O操作非法操作非法,流可恢復流可恢復 hardfail=0 x08 / I/O出現致命錯誤出現致命錯誤,流不可恢復流不可恢復,VC+不支持不支持 9.3 9.3 標準設備的輸入標準設備的輸入/ /輸出輸出點擊查看點擊查看讀取狀態(tài)的有關操作讀取狀態(tài)的有關操作【例【例9.3】提高輸入的健壯性。輸入時需要故提高輸入的健壯性。輸入時需要故意輸錯,以測試健壯性。意輸錯,以測試健壯性。9.3 標準設備的輸入標準設備的輸入/ /輸出輸出全面介紹輸入輸出流中的成員函數全面介紹輸入輸出流中的成員函數輸入流成員函數聲明:輸入流成員函數聲明:字符輸入:字符輸入:istream&istream:get(char
18、 &); istream&istream:get(unsigned char &); istream&istream:get(signed char &);提取一個字符提取一個字符,放在字符型變量中放在字符型變量中9.3 標準設備的輸入標準設備的輸入/ /輸出輸出字符串輸入:字符串輸入:istream&istream:get(char *,int,char=n);istream&istream:get(unsigned char *,int,char=n); istream&istream:get(signed char *,int,char=n); istream&istream:getli
19、ne(char *,int,char=n); istream&istream:getline(unsigned char *,int,char=n); istream&istream:getline(signed char *,int,char=n); 提取的串放在第一個參數為開始地址的存儲區(qū)(不查邊界);第二提取的串放在第一個參數為開始地址的存儲區(qū)(不查邊界);第二個參數為至多提取的字符個數(指定為個參數為至多提取的字符個數(指定為n,最多取,最多取n-1個,再加一個個,再加一個字符串結束符);第三個參數為結束字符,遇此字符則結束,缺省字符串結束符);第三個參數為結束字符,遇此字符則結束,缺
20、省為回車換行符為回車換行符。get系列函數要求單獨提取結束字符。系列函數要求單獨提取結束字符。getline提取字符串時如遇到提取字符串時如遇到指定結束符則提取該結束符,但不保存在串中。指定結束符則提取該結束符,但不保存在串中。這兩個函數都會在這兩個函數都會在提取的一系列字符后加一個串結束符,返回值為對象本身(提取的一系列字符后加一個串結束符,返回值為對象本身(*this)。)。 9.3 標準設備的輸入標準設備的輸入/ /輸出輸出返回最后一次提取的字符數量返回最后一次提取的字符數量,包括回車的包括回車的函數函數gcount() :int istream:gcount(); 讀空(指定一個大的數
21、量)緩沖區(qū)讀空(指定一個大的數量)緩沖區(qū)函數函數ignore() :istream&istream:ignore(int=1,int=EOF);解釋解釋EOF定義和應用定義和應用【例【例9.4】 ignore()和和gcount()函數使用。函數使用。9.3 標準設備的輸入標準設備的輸入/ /輸出輸出輸出流成員函數聲明:輸出流成員函數聲明:ostream&ostream:put(char); /輸出參數字符輸出參數字符ostream&ostream:put(unsigned char);ostream&ostream:put(signed char);ostream&ostream:flush
22、(); /刷新一個輸出流刷新一個輸出流,用于用于cout和和clogC+允許用戶允許用戶重載插入和提取運算符重載插入和提取運算符“”,【例【例9.6】輸出字符串地址。輸出字符串地址。9.4 文件的輸入與輸文件的輸入與輸出出 本節(jié)中文件指的是磁盤文件。本節(jié)中文件指的是磁盤文件。C+根據文件(根據文件(file)內容的數據格式,可分為兩類:二進制文件和文本文件。內容的數據格式,可分為兩類:二進制文件和文本文件。文本文件文本文件由字符序列組成,也稱由字符序列組成,也稱ASCII碼文件,在文本碼文件,在文本文件中存取的最小信息單位為字符(文件中存取的最小信息單位為字符(character),而),而二
23、進制文件二進制文件中存取的最小信息單位為字節(jié)(中存取的最小信息單位為字節(jié)(Byte)。)。9.4.1 文件的打開與關閉文件的打開與關閉 9.4.2 文本文件的讀寫文本文件的讀寫9.4.3 二進制文件的讀寫二進制文件的讀寫 9.4.4 文件的隨機訪問文件的隨機訪問 9.4.5 文件與對象文件與對象 9.4.1 文件的打開與關閉文件的打開與關閉文件的使用步驟如下:文件的使用步驟如下:1說明一個文件流對象,這又被稱為內部文件:說明一個文件流對象,這又被稱為內部文件:ifstream ifile;/只輸入用只輸入用ofstream ofile;/只輸出用只輸出用fstream iofile;/既輸入又
24、輸出用既輸入又輸出用 9.4.1 文件的打開與關閉文件的打開與關閉2使用文件流對象的成員函數打開一個磁盤文件。這樣在文使用文件流對象的成員函數打開一個磁盤文件。這樣在文件流對象和磁盤文件名之間建立聯系。文件流中說明了三個打件流對象和磁盤文件名之間建立聯系。文件流中說明了三個打開文件的成員函數。開文件的成員函數。void ifstream:open(const char*,int =ios:in, int=filebuf:openprot);void ofstream:open(const char *,int=ios:out, int=filebuf:opernprot);void fstre
25、am:open(const char*,int, int=filebuf:openprot); 第一個參數為要打開的磁盤文件名。第二個參數為打開方式,第一個參數為要打開的磁盤文件名。第二個參數為打開方式,有輸入(有輸入(in),輸出(),輸出(out)等,打開方式在)等,打開方式在ios基類中定義為基類中定義為枚舉類型。第三個參數為指定打開文件的保護方式,一般取缺枚舉類型。第三個參數為指定打開文件的保護方式,一般取缺省。省。所以第二步可如下進行:所以第二步可如下進行:iofile.open(“myfile.txt”,ios:in|ios:out);9.4.1 文件的打開與關閉文件的打開與關閉
26、三個文件流類都重載了一個帶缺省參數的三個文件流類都重載了一個帶缺省參數的構造函構造函數數,功能與,功能與open函數一樣:函數一樣:i f s t r e a m : : i f s t r e a m ( c o n s t char*,int=ios:in,int=filebuf:openprot);ofstream:ofstream(const char*,int=ios:out, int=filebuf:openprot);fstream:fstream(const char*,int, int=filebuf:operprot);所以所以1,2兩步可合成:兩步可合成:fstream
27、iofile(”myfile.txt”,ios:in|ios:out);9.4.1 文件的打開與關閉文件的打開與關閉打開文件也應該判斷是否成功,若成功,文件流對打開文件也應該判斷是否成功,若成功,文件流對象值為非零值,不成功為象值為非零值,不成功為0(NULL),),文件流對象文件流對象值物理上就是指它的地址值物理上就是指它的地址。因此打開一個文件完整的程序為:因此打開一個文件完整的程序為:fstream iofile(”myfile.txt”,ios:in|ios:out);if(!iofile)cout”不能打開文件不能打開文件:”myfile,txt”)和插入運算符()和插入運算符(ch
28、; /從輸入設備從輸入設備(串串)讀入一個字符讀入一個字符coutch(istream& is, Reader& rd) Item it; Magazine mg; int type,count; isrd.Namerd.Positionrd.Agerd.Codecount; /A 讀入讀者基本信息讀入讀者基本信息 for( int i=0; itype; /先讀入所借書的類別先讀入所借書的類別(書本書本or雜志雜志) if(type) /如果是雜志如果是雜志 ismg; /讀入一個雜志信息讀入一個雜志信息 rd.AddBook(mg); /將雜志添加到讀者所借書將雜志添加到讀者所借書 els
29、e /書籍書籍 isit; /讀入一個書籍信息讀入一個書籍信息 rd.AddBook(it); /將書籍添加到讀者所借書將書籍添加到讀者所借書 return is; 9.7 9.7 圖書館流通管理系統設計圖書館流通管理系統設計輸出輸出/ /輸入流的應用輸入流的應用重載讀者類插入符,寫入文件:重載讀者類插入符,寫入文件:ostream& operator(ostream& os, Reader& rd) osrd.Name rd.Position rd.Age rd.Code rd.Countern; /輸出讀者基本信息輸出讀者基本信息 Book* p = rd.items; while(p)
30、/輸出讀者所借書輸出讀者所借書 osGetType()GetType() os*(Magazine*)p; /基類指針基類指針轉換轉換為派生類指針輸出對象為派生類指針輸出對象 else osNext; return os; 9.7 9.7 圖書館流通管理系統設計圖書館流通管理系統設計輸出輸出/ /輸入流的應用輸入流的應用下面給雙向鏈表模板類重載提取和插入運算符。下面給雙向鏈表模板類重載提取和插入運算符。templateostream& operator(ostream& os, DblList &dlist) /重載插入運算符,鏈表重載插入運算符,鏈表存入文件存入文件 DblNode *tem
31、pP; int len = dlist.Length(); oslenrlink; while(tempP!=dlist.head) /循環(huán)輸出鏈表各結點數據域循環(huán)輸出鏈表各結點數據域 osInfo; /這里使用前面重載的五種這里使用前面重載的五種“rlink; return os; 9.7 9.7 圖書館流通管理系統設計圖書館流通管理系統設計輸出輸出/ /輸入流的應用輸入流的應用templateistream& operator(istream& is, DblList &dlist) /重載提取運算符,由文件重載提取運算符,由文件重構鏈表重構鏈表 int len; T tt; /結點數據域
32、變量結點數據域變量 islen; /先讀入鏈表長度先讀入鏈表長度 for(int i=0;itt; /讀入結點數據讀入結點數據 /這里使用前面重載的五種這里使用前面重載的五種“”之一,對應類型之一,對應類型T dlist.Insert(tt); /插入鏈表,即建立一個新結點插入鏈表,即建立一個新結點 return is; class Library /封裝圖書館流通業(yè)務的類封裝圖書館流通業(yè)務的類/其它數據成員其它數據成員 ofstream itemFileOut; /文件流對象,保存可借閱書籍數據文件流對象,保存可借閱書籍數據 ifstream itemFileIn; /文件流對象,讀入可借閱
33、書籍數據文件流對象,讀入可借閱書籍數據 ofstream magFileOut;/文件流對象,保存可借閱雜志數據文件流對象,保存可借閱雜志數據 ifstream magFileIn; /文件流對象,讀入可借閱雜志數據文件流對象,讀入可借閱雜志數據 ofstream readerFileOut; /文件流對象,保存讀者數據文件流對象,保存讀者數據 ifstream readerFileIn; /文件流對象,讀入讀者數據文件流對象,讀入讀者數據 ofstream managerFileOut; /文件流對象,保存管理員數據文件流對象,保存管理員數據 ifstream managerFileIn;
34、/文件流對象,讀入管理員數據文件流對象,讀入管理員數據 ofstream loanFileOut; /文件流對象,保存借閱信息數據文件流對象,保存借閱信息數據 ifstream loanFileIn; /文件流對象,讀入借閱信息數據文件流對象,讀入借閱信息數據圖書館類對象是整個流體系運行的源頭,因此為圖書館類添圖書館類對象是整個流體系運行的源頭,因此為圖書館類添加一組輸入文件流對象,一組輸出文件流對象,添加保存信加一組輸入文件流對象,一組輸出文件流對象,添加保存信息和讀入信息的函數。息和讀入信息的函數。public: /其它函數成員其它函數成員 void SaveInfo(); /保存圖書館信
35、息保存圖書館信息 void OpenInfo(); /讀入圖書館信息讀入圖書館信息 /以下在修改款目后分別保存和讀入分類信息以下在修改款目后分別保存和讀入分類信息 void Saveitem(); void Openitem(); ; void Library:SaveInfo() itemFileOut.open(item.txt); /打開各輸出文件流打開各輸出文件流 magFileOut.open(mag.txt); readerFileOut.open(reader.txt); loanFileOut.open(loan.txt); managerFileOut.open(manage
36、r.txt);鏈表存入文件的意思是把鏈表的數據域存入文件,采鏈表存入文件的意思是把鏈表的數據域存入文件,采用對應鏈表類中重載的插入運算符用對應鏈表類中重載的插入運算符“”。9.7 9.7 圖書館流通管理系統設計圖書館流通管理系統設計輸出輸出/ /輸入流的應用輸入流的應用 itemFileOutitemNumnitem; /向各文件存入相應鏈表結點個數及整個鏈表向各文件存入相應鏈表結點個數及整個鏈表 magFileOutmagNumnmag; readerFileOutreaderNumnreader; loanFileOutloanNumnloan; managerFileOutmanager
37、NumnitemNumitem; /讀入鏈表結點個數及并建立整個鏈表對象讀入鏈表結點個數及并建立整個鏈表對象 magFileInmagNummag; readerFileInreaderNumreader; loanFileInloanNumloan; managerFileInmanagerNummanager; itemFileIn.close(); /關閉輸入文件流關閉輸入文件流 建立鏈表對象的意思是用文件中存放的各結點數據域重新生建立鏈表對象的意思是用文件中存放的各結點數據域重新生成鏈表對象的所有結點,采用對應鏈表類中重載的成鏈表對象的所有結點,采用對應鏈表類中重載的“”。 9.7 9
38、.7 圖書館流通管理系統設計圖書館流通管理系統設計輸出輸出/ /輸入流的應用輸入流的應用圖書館流通管理系統的設計到此結束。在本教材的電子文圖書館流通管理系統的設計到此結束。在本教材的電子文檔中有完整的控制臺程序和采用檔中有完整的控制臺程序和采用MFC編制的軟件,可供編制的軟件,可供讀者參考。讀者參考。 SaveInfo和和OpenInfo都在都在Library:Run中調用,在中調用,在Run運行開始時,詢問是否讀入原來的數據,若回答是,調用運行開始時,詢問是否讀入原來的數據,若回答是,調用OpenInfo;否則繼續(xù)。在主菜單選擇;否則繼續(xù)。在主菜單選擇0退出時,先詢問是退出時,先詢問是否保存
39、數據,若回答是,調用否保存數據,若回答是,調用SaveInfo保存數據,否則不保存數據,否則不保存,直接退出。保存,直接退出。第九章第九章 流類庫和輸入流類庫和輸入/ /輸出輸出結束結束謝謝!謝謝!9.2 輸入輸出的格式控制輸入輸出的格式控制訪問訪問x_flags的重載函數定義如下:的重載函數定義如下:inline long ios:flags() const return x_flags; /返回當前標志字返回當前標志字inline long ios:flags(long _l) /參數作為新的標志字參數作為新的標志字,并返回原標志字并返回原標志字 long _l0; _l0=x_flags
40、; x_flags=_l; return _l0; inline long ios:setf(long _l,long _m) long _l0; _l0=x_flag; x_flags=(_l&_m)|(x_flags&(_m); return _l0; /第一個參數為增加的控制第一個參數為增加的控制,第二個參數表示取代原來哪幾位第二個參數表示取代原來哪幾位inline long ios:setf(long _l) /增加控制增加控制(多項多項) long _l0; _l0=x_flags; x_flags|=_l; return _l0; inline long ios:unsetf(lo
41、ng _l) /清除指定位上的控制清除指定位上的控制 long _l0; _l0=x_flags; x_flags &=(_l); return _l0; 9.2 輸入輸出的格式控制輸入輸出的格式控制相關接口函數為相關接口函數為(此類函數僅要求知道用法此類函數僅要求知道用法):inline int ios:width() constreturn x_width; /返回當前域寬返回當前域寬inline int ios:width(int _i) /把參數作為新的域寬把參數作為新的域寬,返回原域寬返回原域寬 int _i0; _i0=(int)x_width; x_width=_i; retur
42、n _i0; inline char ios:fill() constreturn x_fill; /返回當前填充字符返回當前填充字符inline char ios:fill(char _c) /參數作為新填充字符參數作為新填充字符,返回原填充字符返回原填充字符 char _c0; _c0=x_fill; x_fill=_c; return _c0; inline int ios:precision(int i) /參數作為新精度參數作為新精度,返回原精度返回原精度 int _i0; _i0=(int)x_presion; x_presion=_i; return _i0; inline in
43、t ios:precision() const return x_presion; /返回當前精度返回當前精度9.2 輸入輸出的格式控制輸入輸出的格式控制【例【例9.1】整型數輸出?!空蛿递敵?。void main(void) int inum=255; cout”十進制方式十進制方式”inumt; cout.flags(ios:oct|ios:showbase); /八進制帶數制基數輸出是前面加八進制帶數制基數輸出是前面加0,參數等效參數等效0 x00a0 cout”八進制方式八進制方式”inumt; cout.setf(ios:hex); /等效等效0 x0040,因是或關系因是或關系,仍
44、帶基數輸出仍帶基數輸出,格式為格式為0 x. cout”十六進制方式十六進制方式”inumendl;程序輸出:程序輸出:十進制方式十進制方式255 八進制方式八進制方式0377 十六進制方式十六進制方式0 xff9.2 輸入輸出的格式控制輸入輸出的格式控制【例【例9.2】浮點數輸出?!扛↑c數輸出。void main() double fnum=31.415926535; cout”缺省域寬為缺省域寬為:”cout.width()”位位”n; cout”缺省精度為缺省精度為:”cout.precision()”位位”n; cout”缺省表達方式缺省表達方式:”funmn; /按值大小按值大小,自
45、動決定定點還是科學數方式自動決定定點還是科學數方式 cout.setf(ios:scientific,ios:floatfield); cout”科學數表達方式科學數表達方式:”fnumn; cout.setf(ios:fixed,ios:floatfield); /設為定點設為定點,取消科學數取消科學數 cout”定點表達方式定點表達方式:”fnumn; cout.precision(9); /精度為精度為9位,小數點后位,小數點后9位位 cout.setf(ios:scientific,ios:floatfield); cout”9位科學數表達方式位科學數表達方式:”fnumendl;其中
46、其中floatfield為為0 x1800,是,是為了避免浮點數互相沖突的為了避免浮點數互相沖突的雙重規(guī)定,所以是雙重規(guī)定,所以是清除原浮清除原浮點數第點數第13和第和第14兩位兩位,再用,再用新的一位去代替新的一位去代替。9.2 輸入輸出的格式控制輸入輸出的格式控制流操作子(流操作子(setiosflags stream manipulator)可代替流格式)可代替流格式控制成員函數。控制成員函數。但絕大多數流操作子但絕大多數流操作子VC+不支持,其他用不支持,其他用setiosflags(long)對應對應setf(long),unsetiosflags(long)對應對應unsetf(l
47、ong)來實現。來實現。操作符操作符含義含義boolapha把把true和和false表示為字符串表示為字符串*noboolalpha把把true和和false表示為表示為0、1showbase產生前綴,指示數值的進制基數產生前綴,指示數值的進制基數*noshowbase不產生進制基數前綴不產生進制基數前綴showpoint總是顯示小數點總是顯示小數點*noshowpoint只有當小數部分存在是才顯示小數點只有當小數部分存在是才顯示小數點操作符操作符含義含義showpos在非負數值中顯示在非負數值中顯示+*noshowpos在非負數值中不顯示在非負數值中不顯示+*skipws輸入操作符跳過空白
48、字符輸入操作符跳過空白字符noskipws輸入操作符不跳過空白字符輸入操作符不跳過空白字符uppercase在十六進制下顯示在十六進制下顯示0X,科學計數法中顯示,科學計數法中顯示E*nouppercase在十六進制下顯示在十六進制下顯示0 x,科學計數法中顯示,科學計數法中顯示e*dec以十進制顯示以十進制顯示(VC支持支持)hex以十六進制顯示以十六進制顯示(VC支持支持)oct以八進制顯示以八進制顯示(VC支持支持)left將填充字符加到數值的右邊將填充字符加到數值的右邊right將填充字符加到數值的左邊將填充字符加到數值的左邊internal將填充字符加到符號和數值的中間將填充字符加到
49、符號和數值的中間*fixed以小數形式顯示浮點數以小數形式顯示浮點數scientific以科學計數法形式顯示浮點數以科學計數法形式顯示浮點數flush 刷新刷新ostream緩沖區(qū)緩沖區(qū)(VC支持支持)操作符操作符含義含義ends插入字符串結束符,刷新插入字符串結束符,刷新ostream緩沖區(qū)緩沖區(qū)(VC支持支持)endl 插入換行符,然后刷新插入換行符,然后刷新ostream緩沖區(qū)緩沖區(qū)(VC支持支持)ws“吃掉吃掉”空白字符空白字符(VC支持支持)/以下這些參數化的流操作子要求以下這些參數化的流操作子要求#includesetfill(ch)用用ch填充空白字符填充空白字符(VC支持支持)
50、setprecision(n)將浮點精度設置為將浮點精度設置為n (VC支持支持)setw(n) 按照按照w個字符來讀或者寫個字符來讀或者寫(VC支持支持)setbase(b)以進制基數以進制基數b為輸出整數值為輸出整數值(VC支持支持)注:注:*表示缺省的流狀態(tài)表示缺省的流狀態(tài)cin,cout和和clog都是都是緩沖流緩沖流。對輸出而言,僅當輸出緩沖區(qū)滿。對輸出而言,僅當輸出緩沖區(qū)滿才將緩沖區(qū)中的信息輸出,對輸入而言,才將緩沖區(qū)中的信息輸出,對輸入而言,僅當輸入一行結束,僅當輸入一行結束,才開始從緩沖區(qū)中取數據才開始從緩沖區(qū)中取數據,當希望把緩沖區(qū)中的信息立即輸出,當希望把緩沖區(qū)中的信息立即
51、輸出,可用可用flush,加,加endl也有同樣功能,回車并立即顯示,不必等緩也有同樣功能,回車并立即顯示,不必等緩沖區(qū)滿(沖區(qū)滿(endl清空緩沖區(qū))。清空緩沖區(qū))。 讀取狀態(tài)的有關操作如下:讀取狀態(tài)的有關操作如下:inline int ios:rdstate() const return state; /讀取狀態(tài)字讀取狀態(tài)字inline int ios:bad() /返回非法操作位返回非法操作位 return state & badbit;inline void ios:clear(int _i)/人工設置狀態(tài)人工設置狀態(tài),可用來清狀態(tài)可用來清狀態(tài) lock();state=_i;unlo
52、ck(); inline int ios:eof() const return state&eofbit; /返回流結束位返回流結束位inline int ios:fail() const /返回操作非法和操作失敗這兩位返回操作非法和操作失敗這兩位 return state&(badbit|failbit); inline int ios:operator!() const return state&(badbit|failbit); /可用操作符可用操作符!()代替代替fail()inline int ios:good() constreturn state=0; /正常返回正常返回1 9.
53、3 9.3 標準設備的輸入標準設備的輸入/ /輸出輸出【例【例9.3】提高輸入的健壯性。】提高輸入的健壯性。void main() char str256; int i; cout請輸入整數請輸入整數:i; /可輸入非數字字符可輸入非數字字符,下次再輸入若干字符加數字串等進行檢測下次再輸入若干字符加數字串等進行檢測 while(cin.fail() coutcin.rdstate()endl; /輸出狀態(tài)字輸出狀態(tài)字 cin.clear(0); /清狀態(tài)字清狀態(tài)字 cin.getline(str,255); /讀空緩沖區(qū)讀空緩沖區(qū) cout輸入錯誤輸入錯誤,請重新輸入整數請重新輸入整數i; c
54、in.getline(str,256); /讀空緩沖區(qū)讀空緩沖區(qū) cout請輸入字符串請輸入字符串endl; cin.getline(str,255); cout輸入整數為輸入整數為:iendl; cout輸入字符串為輸入字符串為:strendl; 9.3 標準設備的輸入標準設備的輸入/ /輸出輸出用下面的函數返回最后一次提取的字符數量用下面的函數返回最后一次提取的字符數量,包括回車包括回車int istream:gcount() const return x_gcoutnt;還有一個成員函數可用來讀空(指定一個大的數量)緩沖區(qū):還有一個成員函數可用來讀空(指定一個大的數量)緩沖區(qū):istre
55、am&istream:ignore(int=1,int=EOF);第一個參數為要提取的字符數量,缺省為第一個參數為要提取的字符數量,缺省為1;第二個參數表示遇;第二個參數表示遇到該字符則結束,包括該結束字符,但對所提取的字符不保存到該字符則結束,包括該結束字符,但對所提取的字符不保存不處理,作用是空讀。第二個參數的缺省值不處理,作用是空讀。第二個參數的缺省值EOF為文件結束標為文件結束標志。志。在在iostream.h中中EOF定義為定義為-1,在,在int get()函數中,讀入輸入函數中,讀入輸入流結束標志流結束標志Ctrl+Z(Z)時,函數返回)時,函數返回EOF,為了能表示,為了能表示
56、EOF的的“-1”值,返回類型為值,返回類型為int。采用。采用cin.eof()函數,當前所函數,當前所讀為讀為EOF則返回非零,則返回非零,函數自身未從流中讀取。函數自身未從流中讀取。9.3 標準設備的輸入標準設備的輸入/ /輸出輸出【例【例9.4】ignore()和和gcount()函數使用。函數使用。void main() char str255; int i,n; cout輸入字符輸入字符endl; i=cin.get(); /請輸入請輸入Z,一旦輸入一旦輸入Z全部結束全部結束,不能輸入其它不能輸入其它 coutendl; n=cin.rdstate(); /讀取狀態(tài)字讀取狀態(tài)字 c
57、out“狀態(tài)字為:狀態(tài)字為:”nendl; /狀態(tài)字為狀態(tài)字為1,流結束流結束 cout當輸入字符時當輸入字符時,取得的是取得的是:iendl; /輸入輸入Z時時,返回返回EOF,即即-1 if(n=0) cin.ignore(255,n); /清除多余的字符和回車符清除多余的字符和回車符 cin.clear(0); / A 使流恢復正常使流恢復正常 cout輸入字符串輸入字符串1:endl; cin.getline(str,255); 9.3 標準設備的輸入標準設備的輸入/ /輸出輸出 coutendl; cout狀態(tài)字為:狀態(tài)字為:cin.rdstate()endl; i=cin.gcou
58、nt(); cout字符串為字符串為:strt讀入字符數為讀入字符數為:it; cout串長為串長為:strlen(str)endl; cin.clear(0); / A cout輸入字符串輸入字符串2:endl; cin.getline(str,255); coutendl; cout狀態(tài)字為:狀態(tài)字為:cin.rdstate()endl; i=cin.gcount(); cout字符串為字符串為:strt讀入字符數為讀入字符數為:it; cout串長為串長為:strlen(str)endl; 注意,若無兩個注意,若無兩個A行,輸入行,輸入Z時,不再理會余下的所有輸入。時,不再理會余下的所有
59、輸入。9.3 標準設備的輸入標準設備的輸入/ /輸出輸出C+允許用戶允許用戶重載插入和提取運算符重載插入和提取運算符“”,以便以便用戶利用標準的輸入用戶利用標準的輸入/輸出流來輸入輸出流來輸入/輸出自定義的數據類型,輸出自定義的數據類型,實現對象的輸入輸出。重載必須保留原來的使用特性。重實現對象的輸入輸出。重載必須保留原來的使用特性。重載可在用戶定義類中,將重載的運算符的函數說明為該類載可在用戶定義類中,將重載的運算符的函數說明為該類的友元函數:的友元函數:friend istream&operator(istream&,className&);friend ostream&operator”
60、或或“”和和“”或或“”的左操作數;第二個參數為的左操作數;第二個參數為用戶定義類的引用,作為右操作數。用戶定義類的引用,作為右操作數。【例【例9.5】用戶定義的復數類型】用戶定義的復數類型Complex的輸入與輸出。的輸入與輸出。class Complex /見【例見【例5.7】,這里有省略這里有省略,以節(jié)約篇幅以節(jié)約篇幅 double Real,Image;public: Complex(double r=0.0, double i=0.0):Real(r),Image(i);friend ostream&operator(istream&s,Complex&a); ;ostream&op
61、erator(ostream&s,const Complex &z) return s(z.Real,z.Image(istream&s,Complex &a) /格式為格式為d,(d),(d,d) double re=0,im=0; char c=0; sc; if(c=()/是否由括號開始是否由括號開始 srec; /實部實部 if(c=,) simc; /虛部虛部 if(c!=) s.clear(ios:failbit); /漏了括號給一個操作失敗標志漏了括號給一個操作失敗標志 else s.putback(c); /無括號,返回一個字符到輸入緩沖區(qū)無括號,返回一個字符到輸入緩沖區(qū) sr
62、e; /實數實數 if(s)a=Complex(re,im); return s;9.3 9.3 標準設備的輸入標準設備的輸入/ /輸出輸出putback()聲明如下:聲明如下:stream&istream:putback(char);它將最后一次從輸入流中得到的字它將最后一次從輸入流中得到的字符放回到輸入流中符放回到輸入流中。9.3 標準設備的輸入標準設備的輸入/ /輸出輸出【例【例9.6】通常用輸出數組名得到的是數組地址,但字符型】通常用輸出數組名得到的是數組地址,但字符型數組(串)不同,輸出的是數組內容。本例將字符指針強數組(串)不同,輸出的是數組內容。本例將字符指針強制轉換為泛型指針輸
63、出字符串地址。制轉換為泛型指針輸出字符串地址。#includevoid main() char *string1=歡迎學習歡迎學習C+程序設計課程!程序設計課程!; cout串值是:串值是:string1n串地址是:串地址是:(void*)string1(istream&s,Complex &a) /格式為格式為d,(d),(d,d) double re=0,im=0; char c=0; sc; if(c=() /是否由括號開始是否由括號開始 srec; /實部實部 if(c=,) simc; /虛部虛部 if(c!=) s.clear(ios:failbit); /漏了括號給一個操作失敗標
64、志漏了括號給一個操作失敗標志 else s.putback(c); /無括號,返回一個字符到輸入緩沖區(qū)無括號,返回一個字符到輸入緩沖區(qū) sre; /實數實數 if(s)a=Complex(re,im); return s;putback()聲明如下:聲明如下:stream&istream:putback(char);它將最后一次從輸入流中得到的它將最后一次從輸入流中得到的字符放回到輸入流中字符放回到輸入流中。9.3 9.3 標準設備的輸入標準設備的輸入/ /輸出輸出9.4.2 文本文件的讀寫文本文件的讀寫【例【例9.7】復制文件。】復制文件。 void main() ifstream sfil
65、e(d:Ex9_6Ex9_6.cpp); ofstream dfile(e:Ex9_6.cpp); /只能創(chuàng)建文件,不能建立子目錄,如路徑不存在則失敗只能創(chuàng)建文件,不能建立子目錄,如路徑不存在則失敗 char ch; if(!sfile)cout不能打開源文件不能打開源文件: d:Ex9_6Ex9_6.cppendl; exit(1); if(!dfile)cout不能打開目標文件不能打開目標文件:e:Ex9_6.cpp ch) dfile”)運算符在)運算符在缺省情況下是跳過缺省情況下是跳過空白空白(包括空格,制表,(包括空格,制表,backspace和回和回車等)的,這樣拷貝的文件會缺少一
66、些字符。車等)的,這樣拷貝的文件會缺少一些字符。第二第二,該程序能確定文件是否,該程序能確定文件是否拷貝結束拷貝結束。流類成員函數和運。流類成員函數和運算符全是返回本類型的引用,這里就是流文件對象自身,當算符全是返回本類型的引用,這里就是流文件對象自身,當文件結束時,返回文件結束時,返回NULL,這時不再拷貝,退出循環(huán)。,這時不再拷貝,退出循環(huán)。第三第三,拷貝是,拷貝是按字節(jié)進行按字節(jié)進行的,效率很低,按字節(jié)傳遞開銷極的,效率很低,按字節(jié)傳遞開銷極大,但該程序能正確拷貝任意類型的文件,不僅是文本文件大,但該程序能正確拷貝任意類型的文件,不僅是文本文件(看作按字符),二進制文件(看作按字節(jié))也一樣可正確(看作按字符),二進制文件(看作按字節(jié))也一樣可正確完成。如果是文本文件,我們可以按行進行拷貝。完成。如果是文本文件,我們可以按行進行拷貝。第四第四,!sfile中的!是重載的運算符,在狀態(tài)函數中重載,中的!是重載的運算符,在狀態(tài)函數中重載,當該操作出現不正常狀態(tài),返回當該操作出現不正常狀態(tài),返回true?!纠纠?.8】按行復制文本文件】按行復制文本文件。void main() char
- 溫馨提示:
1: 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
2: 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯系上傳者。文件的所有權益歸上傳用戶所有。
3.本站RAR壓縮包中若帶圖紙,網頁內容里面會有圖紙預覽,若沒有圖紙預覽就沒有圖紙。
4. 未經權益所有人同意不得將文件中的內容挪作商業(yè)或盈利用途。
5. 裝配圖網僅提供信息存儲空間,僅對用戶上傳內容的表現方式做保護處理,對用戶上傳分享的文檔內容本身不做任何修改或編輯,并不能對任何下載內容負責。
6. 下載文件中如有侵權或不適當內容,請與我們聯系,我們立即糾正。
7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。