




版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進(jìn)行舉報(bào)或認(rèn)領(lǐng)
文檔簡介
1、第第1313章章 C+C+流和文件流流和文件流 C+語言中沒有專門的輸入語言中沒有專門的輸入/輸出(輸出(I/O)語句,)語句,C+中的中的I/O操作是通過一組標(biāo)準(zhǔn)操作是通過一組標(biāo)準(zhǔn)I/O函數(shù)和函數(shù)和I/O流流來實(shí)現(xiàn)的。來實(shí)現(xiàn)的。 C+的標(biāo)準(zhǔn)的標(biāo)準(zhǔn)I/O函數(shù)是從函數(shù)是從C語言繼承而來的,語言繼承而來的,同時(shí)對同時(shí)對C語言的標(biāo)準(zhǔn)語言的標(biāo)準(zhǔn)I/O函數(shù)進(jìn)行了擴(kuò)充。函數(shù)進(jìn)行了擴(kuò)充。 C+的的I/O流不僅擁有標(biāo)準(zhǔn)流不僅擁有標(biāo)準(zhǔn)I/O函數(shù)的功能,而函數(shù)的功能,而且比且比I/O函數(shù)更方便、更可靠。函數(shù)更方便、更可靠。13.1 什么是流什么是流 C+中把數(shù)據(jù)之間的傳輸操作稱作流。在中把數(shù)據(jù)之間的傳輸操作稱作流
2、。在C+中,中,流既可以表示數(shù)據(jù)從內(nèi)存?zhèn)魉偷侥硞€(gè)載體或設(shè)備中,流既可以表示數(shù)據(jù)從內(nèi)存?zhèn)魉偷侥硞€(gè)載體或設(shè)備中,即輸出流;也可以表示數(shù)據(jù)從某個(gè)載體或設(shè)備傳送即輸出流;也可以表示數(shù)據(jù)從某個(gè)載體或設(shè)備傳送到內(nèi)存緩沖區(qū)變量中,即輸入流。到內(nèi)存緩沖區(qū)變量中,即輸入流。 在進(jìn)行在進(jìn)行I/O操作時(shí),操作步驟如下:操作時(shí),操作步驟如下: (1)打開操作,使流和文件發(fā)生聯(lián)系,建立聯(lián))打開操作,使流和文件發(fā)生聯(lián)系,建立聯(lián)系后的文件才允許數(shù)據(jù)流入或流出;系后的文件才允許數(shù)據(jù)流入或流出; (2)輸入或輸出操作;)輸入或輸出操作; (3)結(jié)束后,使用關(guān)閉操作使文件與流斷開聯(lián))結(jié)束后,使用關(guān)閉操作使文件與流斷開聯(lián)系。系。
3、C+中所有流都是相同的,但操作的文件可以不中所有流都是相同的,但操作的文件可以不同。同。 使用流以后,程序用流統(tǒng)一對各種計(jì)算機(jī)設(shè)備和使用流以后,程序用流統(tǒng)一對各種計(jì)算機(jī)設(shè)備和文件進(jìn)行操作,使程序與設(shè)備、程序與文件無關(guān),從文件進(jìn)行操作,使程序與設(shè)備、程序與文件無關(guān),從而提高了程序設(shè)計(jì)的通用性和靈活性。而提高了程序設(shè)計(jì)的通用性和靈活性。 也就是說,無論與流相聯(lián)系的實(shí)際物理設(shè)備差別也就是說,無論與流相聯(lián)系的實(shí)際物理設(shè)備差別有多大,流都采用相同的方式運(yùn)行。有多大,流都采用相同的方式運(yùn)行。 這種機(jī)制使得流可以跨越物理設(shè)備平臺(tái),實(shí)現(xiàn)流這種機(jī)制使得流可以跨越物理設(shè)備平臺(tái),實(shí)現(xiàn)流的透明運(yùn)作,而與實(shí)際的物理設(shè)備
4、無關(guān)。例如,往顯的透明運(yùn)作,而與實(shí)際的物理設(shè)備無關(guān)。例如,往顯示器上輸出字符和向磁盤文件或打印機(jī)輸出字符,盡示器上輸出字符和向磁盤文件或打印機(jī)輸出字符,盡管接收輸出的物理設(shè)備不同,但具體操作過程是相同管接收輸出的物理設(shè)備不同,但具體操作過程是相同的。的。13.1.1 預(yù)定義流預(yù)定義流 在程序開始運(yùn)行時(shí),在程序開始運(yùn)行時(shí),C+會(huì)自動(dòng)打開會(huì)自動(dòng)打開4個(gè)流,這個(gè)流,這些流是些流是C+流類庫的預(yù)定義流,如下表所列。流類庫的預(yù)定義流,如下表所列。流流含義含義所屬類庫所屬類庫默認(rèn)設(shè)備默認(rèn)設(shè)備cin標(biāo)準(zhǔn)輸入標(biāo)準(zhǔn)輸入iostream.h鍵盤鍵盤cout標(biāo)準(zhǔn)輸出標(biāo)準(zhǔn)輸出iostream.h顯示器顯示器cerr沒
5、有被緩沖的沒有被緩沖的標(biāo)準(zhǔn)錯(cuò)誤輸出標(biāo)準(zhǔn)錯(cuò)誤輸出iostream.h顯示器顯示器clog被緩沖了的標(biāo)被緩沖了的標(biāo)準(zhǔn)錯(cuò)誤輸出準(zhǔn)錯(cuò)誤輸出iostream.h顯示器顯示器 C+的流通過重載運(yùn)算符的流通過重載運(yùn)算符“”執(zhí)行輸出執(zhí)行輸出和輸入操作。和輸入操作。 輸出操作是向流中插入一個(gè)字符序列,因此,在輸出操作是向流中插入一個(gè)字符序列,因此,在流操作中,將運(yùn)算符流操作中,將運(yùn)算符“”稱為稱為提取運(yùn)算符提取運(yùn)算符。1cout cout是與標(biāo)準(zhǔn)輸出設(shè)備連接的預(yù)定義輸出流,是與標(biāo)準(zhǔn)輸出設(shè)備連接的預(yù)定義輸出流,稱為匯。稱為匯。C+的插入運(yùn)算符的插入運(yùn)算符“”向輸出流發(fā)送字符。向輸出流發(fā)送字符。實(shí)際上,位于插入運(yùn)算
6、符右側(cè)的字符串被存儲(chǔ)在實(shí)際上,位于插入運(yùn)算符右側(cè)的字符串被存儲(chǔ)在“”左側(cè)的流中。例如:左側(cè)的流中。例如: cout name number n; cout是數(shù)據(jù)的目的地,插入運(yùn)算符是數(shù)據(jù)的目的地,插入運(yùn)算符“”處流進(jìn)程序。為了保留輸入數(shù)據(jù),輸入語句處流進(jìn)程序。為了保留輸入數(shù)據(jù),輸入語句要求有目的地址,即指定數(shù)據(jù)類型的存儲(chǔ)單元,例如:要求有目的地址,即指定數(shù)據(jù)類型的存儲(chǔ)單元,例如: int i; cin i; 這段代碼所進(jìn)行的操作是:提取運(yùn)算符這段代碼所進(jìn)行的操作是:提取運(yùn)算符“”從從cin參數(shù)中提取一個(gè)整型輸入數(shù)據(jù),并存入一個(gè)對象參數(shù)中提取一個(gè)整型輸入數(shù)據(jù),并存入一個(gè)對象(變量),在此例中即為
7、整型數(shù)(變量),在此例中即為整型數(shù)i。 cin一般連接到標(biāo)準(zhǔn)輸入設(shè)備即鍵盤(默認(rèn)設(shè)一般連接到標(biāo)準(zhǔn)輸入設(shè)備即鍵盤(默認(rèn)設(shè)備)。備)。3cerr cerr類似標(biāo)準(zhǔn)錯(cuò)誤文件。類似標(biāo)準(zhǔn)錯(cuò)誤文件。cerr與與cout的差別在于:的差別在于: (1)cerr是不能重定向的;是不能重定向的; (2)cerr不能被緩沖,它的輸出總是直接傳送到不能被緩沖,它的輸出總是直接傳送到標(biāo)準(zhǔn)輸出設(shè)備上。標(biāo)準(zhǔn)輸出設(shè)備上。 錯(cuò)誤信息是寫到錯(cuò)誤信息是寫到cerr的項(xiàng)。即使在各種其他輸出的項(xiàng)。即使在各種其他輸出語句中,如果使用下列語句,則錯(cuò)誤信息語句中,如果使用下列語句,則錯(cuò)誤信息“Error”總能保證在顯示器上顯示出來:總能保
8、證在顯示器上顯示出來: cerr Error n;4clog clog是不能重定向的,但是可以被緩沖。在某些是不能重定向的,但是可以被緩沖。在某些系統(tǒng)中,由于緩沖,使用系統(tǒng)中,由于緩沖,使用clog代替代替cerr可以改進(jìn)顯示可以改進(jìn)顯示速度:速度: clog Error n;13.1.2 C+的流類庫的流類庫 C+提供了一個(gè)流類庫,流類庫由若干完成提供了一個(gè)流類庫,流類庫由若干完成I/O操作的基礎(chǔ)類以及若干支持特定種類的源和目標(biāo)的操作的基礎(chǔ)類以及若干支持特定種類的源和目標(biāo)的I/O操作類組成。操作類組成。 流類庫的基礎(chǔ)類利用繼承關(guān)系組織起來,其類層流類庫的基礎(chǔ)類利用繼承關(guān)系組織起來,其類層次如
9、下圖所示,這些類的說明如表次如下圖所示,這些類的說明如表13.2所列。所有所列。所有使用流類庫的程序必須用使用流類庫的程序必須用“#include”編譯指令將編譯指令將iostream.h包含進(jìn)來。包含進(jìn)來。 ios istream ostream istrstream istream _withassign ifstream iostream ofstream ostream _withassign ostrstream fstream strstream I/OI/O流類庫的類層次流類庫的類層次輸入流類輸入流類istream通用輸入流類和其他輸入流的基類通用輸入流類和其他輸入流的基類ios
10、tream.hifstream輸入文件流類輸入文件流類fstream.histream_withassigncin的輸入流類的輸入流類iostream.histrstream輸入字符串流類輸入字符串流類strstrea.h輸出流類輸出流類ostream通用輸出流類和其他輸出流的基類通用輸出流類和其他輸出流的基類iostream.hofstream輸出文件流類輸出文件流類fstream.hostream_withassigncout、cerr和和clog的輸出流類的輸出流類iostream.hostrstream輸出字符串流類輸出字符串流類strstrea.hI/O流類流類iostream通用通
11、用I/O流類和其他流類和其他I/O流的基類流的基類iostream.hfstreamI/O文件流類文件流類fstream.hstrstreamI/O字符串流類字符串流類strstrea.h13.2 13.2 格式化格式化I/OI/O 在以前的程序中,所有在以前的程序中,所有I/O采用的格式都是由采用的格式都是由C+流類庫提供的默認(rèn)方式。流類庫提供的默認(rèn)方式。 在實(shí)際應(yīng)用中,常常需要準(zhǔn)確控制數(shù)據(jù)(特別在實(shí)際應(yīng)用中,常常需要準(zhǔn)確控制數(shù)據(jù)(特別是整數(shù)、浮點(diǎn)數(shù)與字符串)的是整數(shù)、浮點(diǎn)數(shù)與字符串)的I/O格式。格式。 流類庫可用兩種方法控制數(shù)據(jù)的格式:使用流類庫可用兩種方法控制數(shù)據(jù)的格式:使用ios類的
12、成員函數(shù)和使用類的成員函數(shù)和使用I/O操縱符。操縱符。13.2.1 使用使用ios成員函數(shù)成員函數(shù) 每一個(gè)每一個(gè)C+流都有自己當(dāng)前的數(shù)據(jù)格式控制狀態(tài),流都有自己當(dāng)前的數(shù)據(jù)格式控制狀態(tài),這些狀態(tài)用一個(gè)長整數(shù)表示,即這些狀態(tài)用一個(gè)長整數(shù)表示,即ios類的數(shù)據(jù)成員類的數(shù)據(jù)成員x_flags,稱為格式化標(biāo)志字。,稱為格式化標(biāo)志字。 這些格式化標(biāo)志字在這些格式化標(biāo)志字在ios類中定義為公有的枚舉量。類中定義為公有的枚舉量。 在在iostream.h頭文件中定義了以下枚舉類型:頭文件中定義了以下枚舉類型:enum skipws = 0 x0001, /跳過輸入中的空白跳過輸入中的空白(空格、制表符、回車、
13、換行等空格、制表符、回車、換行等) left = 0 x0002, /輸出左對齊輸出左對齊 right = 0 x0004, /輸出右對齊輸出右對齊 internal = 0 x0008, /在符號(hào)或基位與數(shù)值之間補(bǔ)齊空格在符號(hào)或基位與數(shù)值之間補(bǔ)齊空格 dec = 0 x0010, /按十進(jìn)制按十進(jìn)制I/O oct = 0 x0020, /按八進(jìn)制按八進(jìn)制I/O hex = 0 x0040, /按十六進(jìn)制按十六進(jìn)制I/O showbase = 0 x0080, /輸出數(shù)制的基輸出數(shù)制的基 showpoint = 0 x0100, /強(qiáng)制浮點(diǎn)數(shù)輸出小數(shù)點(diǎn)強(qiáng)制浮點(diǎn)數(shù)輸出小數(shù)點(diǎn) uppercase
14、= 0 x0200, /十六進(jìn)制采用大寫輸出十六進(jìn)制采用大寫輸出 showpos = 0 x0400, /在正數(shù)前加上在正數(shù)前加上“+” scientific = 0 x0800, /浮點(diǎn)數(shù)使用科學(xué)記數(shù)法浮點(diǎn)數(shù)使用科學(xué)記數(shù)法 fixed = 0 x1000, /浮點(diǎn)數(shù)使用普通記數(shù)法浮點(diǎn)數(shù)使用普通記數(shù)法 unitbuf = 0 x2000, /每次插入后刷新所有流每次插入后刷新所有流 stdio = 0 x4000 /每次插入后刷新標(biāo)準(zhǔn)輸出和標(biāo)準(zhǔn)錯(cuò)誤輸出流每次插入后刷新標(biāo)準(zhǔn)輸出和標(biāo)準(zhǔn)錯(cuò)誤輸出流;(1)setf() 成員函數(shù)成員函數(shù)setf()用于設(shè)置狀態(tài)標(biāo)志。例如,設(shè)置輸用于設(shè)置狀態(tài)標(biāo)志。例如,
15、設(shè)置輸出流出流cout的的showbase標(biāo)志使用如下語句:標(biāo)志使用如下語句: cout.setf(ios:showbase); 設(shè)置輸入流設(shè)置輸入流cin的的skipws標(biāo)志使用如下語句:標(biāo)志使用如下語句: cin.setf(ios:skipws); 注意:格式標(biāo)志前的限定注意:格式標(biāo)志前的限定“ios:”不可缺少,因不可缺少,因?yàn)檫@些標(biāo)志是在為這些標(biāo)志是在ios類中定義的。類中定義的。 在在setf()中還可用位或操作中還可用位或操作“|”將多個(gè)標(biāo)志連在一將多個(gè)標(biāo)志連在一起。例如:起。例如: cout.setf(ios:scientific|ios:showpoint); 同時(shí)設(shè)置同時(shí)設(shè)置
16、scientific和和showpoint兩個(gè)標(biāo)志。兩個(gè)標(biāo)志。(2)unsetf() 成員函數(shù)成員函數(shù)unsetf()用來取消格式標(biāo)志,用來取消格式標(biāo)志,unsetf()的的用法與用法與setf()相似。相似。(3)flags() 成員函數(shù)成員函數(shù)flags()用于獲取當(dāng)前格式標(biāo)志的狀態(tài),用于獲取當(dāng)前格式標(biāo)志的狀態(tài),即返回保護(hù)成員即返回保護(hù)成員x_flags的當(dāng)前值。的當(dāng)前值。(4)precision() 該函數(shù)的說明如下:該函數(shù)的說明如下: int precision(int num); 用于設(shè)置或返回(不帶參數(shù)時(shí))浮點(diǎn)數(shù)的輸出精用于設(shè)置或返回(不帶參數(shù)時(shí))浮點(diǎn)數(shù)的輸出精度,也就是通過這個(gè)公
17、共成員函數(shù)設(shè)置度,也就是通過這個(gè)公共成員函數(shù)設(shè)置ios類的保護(hù)類的保護(hù)數(shù)據(jù)成員數(shù)據(jù)成員x_precision的值,該成員的默認(rèn)值為的值,該成員的默認(rèn)值為6。 precision()函數(shù)的設(shè)置值一直有效,直到下一個(gè)函數(shù)的設(shè)置值一直有效,直到下一個(gè)precision()函數(shù)改變該值為止。函數(shù)改變該值為止。(5)width() 該函數(shù)的說明如下:該函數(shù)的說明如下: int width(int len); 用于設(shè)置或返回(不帶參數(shù)時(shí))輸出數(shù)據(jù)的字段用于設(shè)置或返回(不帶參數(shù)時(shí))輸出數(shù)據(jù)的字段寬度,也就是通過這個(gè)公共成員函數(shù)設(shè)置寬度,也就是通過這個(gè)公共成員函數(shù)設(shè)置ios類的保類的保護(hù)數(shù)據(jù)成員護(hù)數(shù)據(jù)成員x_
18、width的值。的值。 width()函數(shù)的設(shè)置值只對下一個(gè)輸出有效。函數(shù)的設(shè)置值只對下一個(gè)輸出有效。(6)fill() 該函數(shù)的說明如下:該函數(shù)的說明如下: char fill(char ch); 用于設(shè)置或返回(不帶參數(shù)時(shí))輸出的填充字用于設(shè)置或返回(不帶參數(shù)時(shí))輸出的填充字符,也就是通過這個(gè)公共成員函數(shù)設(shè)置符,也就是通過這個(gè)公共成員函數(shù)設(shè)置ios類的保護(hù)類的保護(hù)數(shù)據(jù)成員數(shù)據(jù)成員x_fill的值,該成員的默認(rèn)值為空格。的值,該成員的默認(rèn)值為空格。 fill ()函數(shù)的設(shè)置值一直有效,直到下一個(gè)函數(shù)的設(shè)置值一直有效,直到下一個(gè)fill()函數(shù)改變該值為止。函數(shù)改變該值為止。【例】【例】 分析
19、以下程序的執(zhí)行結(jié)果。分析以下程序的執(zhí)行結(jié)果。#include void main() int n=123; double d=1234.5678; cout.precision(10); cout.width(10); cout.fill(*); cout n endl; cout d endl; cout.precision(6); cout.width(6); cout n endl; cout d endl; *123 1234.5678 *123 1234.57 右對齊右對齊13.2.2 使用使用I/O操縱符操縱符 除除ios類成員函數(shù)之外,類成員函數(shù)之外,C+的流類庫還提供了另的流類
20、庫還提供了另一種更方便的一種更方便的I/O格式化方法,這種方法使用一種稱格式化方法,這種方法使用一種稱為操縱符的特殊函數(shù),操縱符的特點(diǎn)是可以直接包含為操縱符的特殊函數(shù),操縱符的特點(diǎn)是可以直接包含在在I/O表達(dá)式中。表達(dá)式中。 所有不帶形參的操縱符都定義在頭文件所有不帶形參的操縱符都定義在頭文件iostream.h中,而帶形參的操縱符則定義在頭文件中,而帶形參的操縱符則定義在頭文件iomanip.h中,因而使用相應(yīng)的操縱符就必須包含相中,因而使用相應(yīng)的操縱符就必須包含相應(yīng)的頭文件。表應(yīng)的頭文件。表13.3列出了這些列出了這些I/O操縱符。操縱符。 已在第已在第3章已介紹,這是不再討論。章已介紹,
21、這是不再討論。13.3 13.3 重載重載I/OI/O運(yùn)算符運(yùn)算符 C+的的I/O系統(tǒng)的另一個(gè)優(yōu)點(diǎn)是可以重載系統(tǒng)的另一個(gè)優(yōu)點(diǎn)是可以重載I/O運(yùn)運(yùn)算符。通過重載算符。通過重載I/O運(yùn)算符,可以建立適合于類需運(yùn)算符,可以建立適合于類需要的輸入和輸出界面。要的輸入和輸出界面。 I/O運(yùn)算符重載的實(shí)質(zhì)就是把用于變量輸入輸運(yùn)算符重載的實(shí)質(zhì)就是把用于變量輸入輸出的運(yùn)算符轉(zhuǎn)化為對于類對象的輸入輸出操作。出的運(yùn)算符轉(zhuǎn)化為對于類對象的輸入輸出操作。13.3.1 重載輸出運(yùn)算符重載輸出運(yùn)算符“” 在在C+中,輸出操作稱為插入,中,輸出操作稱為插入,“”稱為插入稱為插入運(yùn)算符。當(dāng)重載輸出運(yùn)算符運(yùn)算符。當(dāng)重載輸出運(yùn)算
22、符“”用于輸出時(shí),相當(dāng)用于輸出時(shí),相當(dāng)于創(chuàng)建一個(gè)插入符函數(shù)。插入符函數(shù)的格式如下:于創(chuàng)建一個(gè)插入符函數(shù)。插入符函數(shù)的格式如下: friend ostream & operator (ostream & stream,類名類名 & 類引用名類引用名) 函數(shù)體函數(shù)體; return stream; 該插入符函數(shù)是以友元方式說明的。其中的第一該插入符函數(shù)是以友元方式說明的。其中的第一個(gè)參數(shù)是個(gè)參數(shù)是ostream類對象的一個(gè)引用,即類對象的一個(gè)引用,即stream必須必須是一個(gè)輸出流。是一個(gè)輸出流?!邦愐妹愐妹苯邮沾敵龅膶ο?。接收待輸出的對象。該函數(shù)返回該函數(shù)返回ostream的一個(gè)引用的
23、一個(gè)引用stream?!昂瘮?shù)體函數(shù)體”中給出實(shí)現(xiàn)該插入符重載目的的代碼。中給出實(shí)現(xiàn)該插入符重載目的的代碼?!纠俊纠?分析以下程序的執(zhí)行結(jié)果。分析以下程序的執(zhí)行結(jié)果。#include class Sample int x,y;public: Sample(int m,int n) x=m;y=n; friend ostream & operator (ostream & stream,Sample & s) cout x= s.x ,y= s.y endl; return stream; ;void main() Sample A(1,2),B(3,4); cout A ” 在在C+中,中,
24、“”運(yùn)算符稱為提取運(yùn)算符,對它進(jìn)運(yùn)算符稱為提取運(yùn)算符,對它進(jìn)行重載的函數(shù)稱為提取符函數(shù)。這個(gè)運(yùn)算符函數(shù)接收行重載的函數(shù)稱為提取符函數(shù)。這個(gè)運(yùn)算符函數(shù)接收流的輸入信息。其格式如下:流的輸入信息。其格式如下: friend istream & operator (istream & stream,類名類名 & 類引用名類引用名) 函數(shù)體函數(shù)體; return stream; 該提取符函數(shù)是以友元方式說明的。其中的第一該提取符函數(shù)是以友元方式說明的。其中的第一個(gè)參數(shù)是個(gè)參數(shù)是istream類對象的一個(gè)引用,即類對象的一個(gè)引用,即stream必須是必須是一個(gè)輸入流。一個(gè)輸入流?!邦愐妹愐妹苯邮?/p>
25、輸入對象的引用。該接收輸入對象的引用。該函數(shù)返回函數(shù)返回istream的一個(gè)引用的一個(gè)引用stream?!昂瘮?shù)體函數(shù)體”中給中給出實(shí)現(xiàn)該提取符重載目的的代碼。出實(shí)現(xiàn)該提取符重載目的的代碼?!纠俊纠?分析以下程序的執(zhí)行結(jié)果。分析以下程序的執(zhí)行結(jié)果。#include class Sample int x,y;public: Sample() friend istream & operator (istream & stream,Sample & s) cout 輸入輸入x和和y的值的值 endl; cout s.x; cout s.y; return stream; friend ostrea
26、m & operator (ostream & stream,Sample & s) cout 輸出輸出x和和y的值的值 endl; cout x= s.x ,y= s.y A; cout A; 輸入輸入x和和y的值的值 x:5 y:8 輸出輸出x和和y的值的值 x=5,y=813.4 13.4 檢測流操作的錯(cuò)誤檢測流操作的錯(cuò)誤 在在I/O流的操作過程中可能出現(xiàn)各種錯(cuò)誤,每一個(gè)流的操作過程中可能出現(xiàn)各種錯(cuò)誤,每一個(gè)流都有一個(gè)狀態(tài)標(biāo)志字,以指示是否發(fā)生了錯(cuò)誤以及流都有一個(gè)狀態(tài)標(biāo)志字,以指示是否發(fā)生了錯(cuò)誤以及出現(xiàn)了哪種類型的錯(cuò)誤,這種處理技術(shù)與格式控制標(biāo)出現(xiàn)了哪種類型的錯(cuò)誤,這種處理技術(shù)與格式控制
27、標(biāo)志字是相同的。志字是相同的。ios類定義了以下枚舉類型:類定義了以下枚舉類型: enum io_state goodbit =0 x00,/不設(shè)置任何位,一切正常不設(shè)置任何位,一切正常 eofbit =0 x01, /輸入流已經(jīng)結(jié)束,無字符可讀入輸入流已經(jīng)結(jié)束,無字符可讀入 failbit =0 x02, /上次讀上次讀/寫操作失敗,但流仍可使用寫操作失敗,但流仍可使用 badbit =0 x04, /試圖作無效的讀試圖作無效的讀/寫操作,流不再可用寫操作,流不再可用 hardfail=0 x80 /不可恢復(fù)的嚴(yán)重錯(cuò)誤不可恢復(fù)的嚴(yán)重錯(cuò)誤 ; 對應(yīng)于這個(gè)標(biāo)志字各狀態(tài)位,對應(yīng)于這個(gè)標(biāo)志字各狀態(tài)位
28、,ios類還提供了以下類還提供了以下成員函數(shù)來檢測或設(shè)置流的狀態(tài):成員函數(shù)來檢測或設(shè)置流的狀態(tài): int rdstate(); /返回流的當(dāng)前狀態(tài)標(biāo)志字返回流的當(dāng)前狀態(tài)標(biāo)志字 int eof(); /返回非返回非0值表示到達(dá)文件尾值表示到達(dá)文件尾 int fail(); /返回非返回非0值表示操作失敗值表示操作失敗 int bad(); /返回非返回非0值表示出現(xiàn)錯(cuò)誤值表示出現(xiàn)錯(cuò)誤 int good(); /返回非返回非0值表示流操作正常值表示流操作正常 int clear(int flag=0); /將流的狀態(tài)設(shè)置為將流的狀態(tài)設(shè)置為flag 為提高程序的可靠性,我們應(yīng)在程序中檢測為提高程序的
29、可靠性,我們應(yīng)在程序中檢測I/O流流的操作是否正常。當(dāng)檢測到流操作出現(xiàn)錯(cuò)誤時(shí),可以的操作是否正常。當(dāng)檢測到流操作出現(xiàn)錯(cuò)誤時(shí),可以通過異常處理來解決問題。通過異常處理來解決問題。13.5 13.5 文文 件件 流流 文件是存儲(chǔ)在磁盤、磁帶等外部設(shè)備上的數(shù)據(jù)集文件是存儲(chǔ)在磁盤、磁帶等外部設(shè)備上的數(shù)據(jù)集合,每一個(gè)文件都必須有一個(gè)惟一名字。合,每一個(gè)文件都必須有一個(gè)惟一名字。 使用文件前必須首先打開,使用完畢后必須關(guān)閉使用文件前必須首先打開,使用完畢后必須關(guān)閉文件。文件。 對文件的操作是由文件流類完成的。文件流類在對文件的操作是由文件流類完成的。文件流類在流與文件之間建立連接,使用這些文件流類必須用流
30、與文件之間建立連接,使用這些文件流類必須用#include編譯指令將頭文件編譯指令將頭文件fstream.h包含進(jìn)來。包含進(jìn)來。13.5.1 文件的打開與關(guān)閉文件的打開與關(guān)閉 流可以分為流可以分為3類:輸入流、輸出流以及輸入類:輸入流、輸出流以及輸入/輸出輸出流,相應(yīng)地必須將流說明為流,相應(yīng)地必須將流說明為ifstream、ofstream以及以及fstream類的對象。例如:類的對象。例如: ifstream ifile; /說明一個(gè)輸入流說明一個(gè)輸入流 ofstream ofile; /說明一個(gè)輸出流說明一個(gè)輸出流 fstream iofile; /說明說明個(gè)輸入個(gè)輸入/輸出流輸出流 說明
31、了流對象之后,可使用函數(shù)說明了流對象之后,可使用函數(shù)open()打開文件。打開文件。文件的打開即是在流與文件之間建立一個(gè)連接。文件的打開即是在流與文件之間建立一個(gè)連接。open()的函數(shù)原型為:的函數(shù)原型為: void open(const char * filename, int mode, int prot=filebuf:openprot); 其中,其中,filename是文件名字,它可包含路徑說明。是文件名字,它可包含路徑說明。 mode說明文件打開的模式,它對文件的操作影響說明文件打開的模式,它對文件的操作影響重大,重大,mode的取值必須是以下值之一:的取值必須是以下值之一: io
32、s:in 打開文件進(jìn)行讀操作打開文件進(jìn)行讀操作 ios:out 打開文件進(jìn)行寫操作打開文件進(jìn)行寫操作 ios:ate 打開時(shí)文件指針定位到文件尾打開時(shí)文件指針定位到文件尾 ios:app 添加模式,所有增加都在文件尾部進(jìn)行添加模式,所有增加都在文件尾部進(jìn)行 ios:trunc 如果文件已存在則清空原文件如果文件已存在則清空原文件 ios:nocreate 如果文件不存在則打開失敗如果文件不存在則打開失敗 ios:noreplace 如果文件存在則打開失敗如果文件存在則打開失敗 ios:binary 二進(jìn)制文件(非文本文件)二進(jìn)制文件(非文本文件) 對于對于ifstream流,流,mode的默認(rèn)
33、值為的默認(rèn)值為ios:in;對于;對于ofstream流,流,mode的默認(rèn)值為的默認(rèn)值為ios:out。 prot決定文件的訪問方式,取值如下:決定文件的訪問方式,取值如下: 0 普通文件普通文件 1 只讀文件只讀文件 2 隱含文件隱含文件 4 系統(tǒng)文件系統(tǒng)文件 一般情況下,該訪問方式使用默認(rèn)值。一般情況下,該訪問方式使用默認(rèn)值。 與其他狀態(tài)標(biāo)志一樣,與其他狀態(tài)標(biāo)志一樣,mode的符號(hào)常量可以用位的符號(hào)常量可以用位或運(yùn)算或運(yùn)算“|”組合在一起,如組合在一起,如ios:in|ios:binary表示以表示以只讀方式打開二進(jìn)制文件。例如:只讀方式打開二進(jìn)制文件。例如: ifstream ifil
34、e; ifile.open(c:vcabc.txt,ios:ate);表示以文本文件形式打開表示以文本文件形式打開C:vc目錄下的目錄下的abc.txt文件,文件,文件指針定位到文件尾,準(zhǔn)備進(jìn)行讀文件操作。而文件指針定位到文件尾,準(zhǔn)備進(jìn)行讀文件操作。而操作:操作: ofstream ofile; ofile.open(c:vcabc.txt,ios:binary);表示以二進(jìn)制文件形式打開表示以二進(jìn)制文件形式打開C:vc目錄下的目錄下的abc.txt文文件,準(zhǔn)備進(jìn)行寫文件操作。件,準(zhǔn)備進(jìn)行寫文件操作。 其中,文件名中其中,文件名中“”的第一個(gè)的第一個(gè)“”為轉(zhuǎn)義字符。為轉(zhuǎn)義字符。 除了除了ope
35、n()成員函數(shù)外,成員函數(shù)外,ifstream、ofstream和和fstream三類流的構(gòu)造函數(shù)也可以打開文件,其參數(shù)同三類流的構(gòu)造函數(shù)也可以打開文件,其參數(shù)同open()函數(shù)。例如:函數(shù)。例如: ifstream ifile(c:vcabc.txt ); 說明一個(gè)輸入流對象的同時(shí),將這個(gè)流與文件說明一個(gè)輸入流對象的同時(shí),將這個(gè)流與文件“c:vcabc.txt”連接起來,使流連接起來,使流ifile可以用文本形式對可以用文本形式對該文件進(jìn)行讀操作。該文件進(jìn)行讀操作。13.5.2 文件的讀寫文件的讀寫 通過打開文件就建立通過打開文件就建立I/O流與文本文件的連接,之流與文本文件的連接,之后就可
36、以進(jìn)行文件的讀寫操作了。后就可以進(jìn)行文件的讀寫操作了。1文件讀寫方法文件讀寫方法 在在C+中提供了幾種文件讀寫方法。中提供了幾種文件讀寫方法。 (1)使用流運(yùn)算符直接讀寫。)使用流運(yùn)算符直接讀寫。 文件的讀文件的讀/寫操作可以直接使用流的插入運(yùn)算符寫操作可以直接使用流的插入運(yùn)算符“”,這些運(yùn)算符將完成文件,這些運(yùn)算符將完成文件的字符轉(zhuǎn)換工作。的字符轉(zhuǎn)換工作。 (2)使用流成員函數(shù)。)使用流成員函數(shù)。 常用的輸出流成員函數(shù)如下:常用的輸出流成員函數(shù)如下: put函數(shù)函數(shù) 該函數(shù)把一個(gè)字符寫到輸出流中。下面該函數(shù)把一個(gè)字符寫到輸出流中。下面兩個(gè)語句默認(rèn)是相同的,但第二個(gè)受該流的格式化參兩個(gè)語句默認(rèn)
37、是相同的,但第二個(gè)受該流的格式化參數(shù)的影響:數(shù)的影響: cout.put(A); /精確地輸出一個(gè)字符精確地輸出一個(gè)字符 cout )很)很相似,主要的不同點(diǎn)是相似,主要的不同點(diǎn)是get函數(shù)在讀取數(shù)據(jù)時(shí)包括空白函數(shù)在讀取數(shù)據(jù)時(shí)包括空白字符,而提取運(yùn)算符在默認(rèn)情況下拒絕接受空白字符。字符,而提取運(yùn)算符在默認(rèn)情況下拒絕接受空白字符。 getline函數(shù)函數(shù) 該函數(shù)的功能是允許從輸入流中讀該函數(shù)的功能是允許從輸入流中讀取多個(gè)字符,并且允許指定輸入終止字符(默認(rèn)值是取多個(gè)字符,并且允許指定輸入終止字符(默認(rèn)值是換行字符),在讀取完成后,從讀取的內(nèi)容中刪除該換行字符),在讀取完成后,從讀取的內(nèi)容中刪除該
38、終止字符。終止字符。 read函數(shù)函數(shù) 該函數(shù)從一個(gè)文件讀字節(jié)到一個(gè)指定該函數(shù)從一個(gè)文件讀字節(jié)到一個(gè)指定的存儲(chǔ)器區(qū)域,由長度參數(shù)確定要讀的字節(jié)數(shù)。雖然的存儲(chǔ)器區(qū)域,由長度參數(shù)確定要讀的字節(jié)數(shù)。雖然給出長度參數(shù),但當(dāng)遇到文件結(jié)束或者在文本模式文給出長度參數(shù),但當(dāng)遇到文件結(jié)束或者在文本模式文件中遇到文件結(jié)束標(biāo)記字符時(shí)讀就結(jié)束。件中遇到文件結(jié)束標(biāo)記字符時(shí)讀就結(jié)束。2文本文件的讀寫文本文件的讀寫 文本文件只適用于那些解釋為文本文件只適用于那些解釋為ASCII碼的文件。碼的文件。處理文本文件時(shí)將自動(dòng)作一些字符轉(zhuǎn)換,如輸出換處理文本文件時(shí)將自動(dòng)作一些字符轉(zhuǎn)換,如輸出換行字符行字符0 x0A時(shí)將轉(zhuǎn)換為回車時(shí)
39、將轉(zhuǎn)換為回車0 x0D與換行與換行0 x0A兩個(gè)字兩個(gè)字符存入文本文件,讀入時(shí)也會(huì)將回車與換行兩個(gè)字符存入文本文件,讀入時(shí)也會(huì)將回車與換行兩個(gè)字符合并為一個(gè)換行字符,這樣內(nèi)存中的字符與寫入符合并為一個(gè)換行字符,這樣內(nèi)存中的字符與寫入文件中的字符之間就不再是一一對應(yīng)關(guān)系。文件中的字符之間就不再是一一對應(yīng)關(guān)系。 文本文件的結(jié)束以文本文件的結(jié)束以ASCII碼的控制字符碼的控制字符0 x1A表示。表示?!纠俊纠?分析以下程序的執(zhí)行結(jié)果。分析以下程序的執(zhí)行結(jié)果。#include #include int main() ofstream ofile(test); /打開打開test文件用于寫,即輸出文
40、件用于寫,即輸出 if (!ofile) cout test文件不能打開文件不能打開 endl; return 0; ofile This book is C+ 12345 endl; ofile.close(); ifstream ifile(test); /打開打開test文件用于讀,即輸入文件用于讀,即輸入 if (!ifile) cout test文件不能打開文件不能打開 str; ifile.close(); cout str endl; return 1; 本程序先在當(dāng)前目錄下建立一本程序先在當(dāng)前目錄下建立一個(gè)個(gè)test文本文件,并寫入文本文件,并寫入“This book is C
41、+ 12345”數(shù)據(jù),然后打數(shù)據(jù),然后打開該文件,將其中的數(shù)據(jù)輸入到開該文件,將其中的數(shù)據(jù)輸入到變量變量str中,由于讀時(shí)遇到空格時(shí)中,由于讀時(shí)遇到空格時(shí)終止,所以終止,所以str為為“This”。程序的。程序的執(zhí)行結(jié)果如下:執(zhí)行結(jié)果如下: This 【例】【例】 編寫一個(gè)程序,將文本文件編寫一個(gè)程序,將文本文件abc.txt復(fù)制到復(fù)制到文本文件文本文件xyz.txt。 解:使用輸入流成員函數(shù)解:使用輸入流成員函數(shù)get()從文本文件從文本文件abc.txt中讀取一個(gè)字符中讀取一個(gè)字符ch,然后使用輸出流成員函數(shù),然后使用輸出流成員函數(shù)put()將字符將字符ch寫入文本文件寫入文本文件xyz.
42、txt中,繼續(xù)這一過程直到中,繼續(xù)這一過程直到get()讀完為止。實(shí)現(xiàn)本例功能的程序如下:讀完為止。實(shí)現(xiàn)本例功能的程序如下:#include #include int main() ifstream ifile(abc.txt); char ch; if (!ifile) cout abc.txt文件不能打開文件不能打開 endl; return 0; ofstream ofile(xyz.txt); if (!ofile) cout xyz.txt文件不能打開文件不能打開 endl; return 0; while (ifile.get(ch) ofile.put(ch); ifile.cl
43、ose(); ofile.close(); return 1;3二進(jìn)制文件的讀寫二進(jìn)制文件的讀寫 二進(jìn)制文件不同于文本文件,它可用于任何類二進(jìn)制文件不同于文本文件,它可用于任何類型的文件(包括文本文件),讀寫二進(jìn)制文件的字型的文件(包括文本文件),讀寫二進(jìn)制文件的字符不作任何轉(zhuǎn)換,讀寫的字符與文件之間是完全一符不作任何轉(zhuǎn)換,讀寫的字符與文件之間是完全一致的。致的。 一般地,對二進(jìn)制文件的讀寫可采用兩種方法:一般地,對二進(jìn)制文件的讀寫可采用兩種方法:一種是使用一種是使用get()和和put();另一種是使用;另一種是使用read()和和write()。 【例】以下程序建立一個(gè)輸出文件流并將一個(gè)【
44、例】以下程序建立一個(gè)輸出文件流并將一個(gè)Date結(jié)構(gòu)體變量的二進(jìn)制值寫入到該文件中。結(jié)構(gòu)體變量的二進(jìn)制值寫入到該文件中。 #include struct Date int mo,da,yr; ; void main() Date dt=2,20,2001; ofstream ofile(data.dat,ios:binary); ofile.write(char *)&dt,sizeof dt); ofile.close(); 4文件的隨機(jī)讀寫文件的隨機(jī)讀寫 每一個(gè)文件都有兩個(gè)指針:一個(gè)是讀指針,說明每一個(gè)文件都有兩個(gè)指針:一個(gè)是讀指針,說明輸入操作當(dāng)前在文件中的位置;另一個(gè)是寫指針,說輸入操作
45、當(dāng)前在文件中的位置;另一個(gè)是寫指針,說明下次寫操作的當(dāng)前位置。明下次寫操作的當(dāng)前位置。 每次執(zhí)行輸入或輸出時(shí),相應(yīng)的讀每次執(zhí)行輸入或輸出時(shí),相應(yīng)的讀/寫指針將自寫指針將自動(dòng)向后移動(dòng)。動(dòng)向后移動(dòng)。 C+語言的文件流不僅可以按這種順序方式進(jìn)行語言的文件流不僅可以按這種順序方式進(jìn)行讀讀/寫,而且還可以隨機(jī)地移動(dòng)文件的讀寫,而且還可以隨機(jī)地移動(dòng)文件的讀/寫指針。有寫指針。有一些外部設(shè)備(如磁帶、行式打印機(jī)等)關(guān)聯(lián)的流只一些外部設(shè)備(如磁帶、行式打印機(jī)等)關(guān)聯(lián)的流只能作順序訪問,但在許多情況下使用隨機(jī)方式訪問文能作順序訪問,但在許多情況下使用隨機(jī)方式訪問文件更加方便靈活。件更加方便靈活。(1)輸出流隨機(jī)
46、訪問函數(shù))輸出流隨機(jī)訪問函數(shù) 輸出流隨機(jī)訪問函數(shù)有輸出流隨機(jī)訪問函數(shù)有seekp和和tellp。 一個(gè)輸出文件流保存一個(gè)內(nèi)部指針以指出下一一個(gè)輸出文件流保存一個(gè)內(nèi)部指針以指出下一次寫數(shù)據(jù)的位置。次寫數(shù)據(jù)的位置。seekp成員函數(shù)設(shè)置這個(gè)指針,因成員函數(shù)設(shè)置這個(gè)指針,因此可以以隨機(jī)方式向磁盤文件輸出。此可以以隨機(jī)方式向磁盤文件輸出。tellp成員函數(shù)返成員函數(shù)返回該文件位置指針值。這兩個(gè)成員函數(shù)的原型如下:回該文件位置指針值。這兩個(gè)成員函數(shù)的原型如下: ostream & ostream:seekp(流中的位置流中的位置); ostream & ostream:seekp(偏移量偏移量,參照位置
47、參照位置); streampos ostream:tellp(); 其中,其中,streampos被定義為被定義為long型,并以字節(jié)型,并以字節(jié)數(shù)為單位。數(shù)為單位?!皡⒄瘴恢脜⒄瘴恢谩本哂腥缦潞x:具有如下含義: cur=1 相對于當(dāng)前寫指針?biāo)付ǖ奈恢?。相對于?dāng)前寫指針?biāo)付ǖ奈恢谩?beg=0 相對于流的開始位置。相對于流的開始位置。 end=2 相對于流的結(jié)尾處。相對于流的結(jié)尾處。(2)輸入流隨機(jī)訪問函數(shù)。)輸入流隨機(jī)訪問函數(shù)。 輸入流隨機(jī)訪問函數(shù)有輸入流隨機(jī)訪問函數(shù)有seekg和和tellg。 在輸入文件流中,保留著一個(gè)指向文件中下一在輸入文件流中,保留著一個(gè)指向文件中下一個(gè)將要讀數(shù)據(jù)的位置的內(nèi)部指針,可以用個(gè)將要讀數(shù)據(jù)的位置的內(nèi)部指針,可以用seekg函數(shù)函數(shù)來設(shè)置這個(gè)指針。使用來設(shè)置這個(gè)指針。使用seekg可以實(shí)現(xiàn)面向記錄的數(shù)可以實(shí)現(xiàn)面向記錄的數(shù)據(jù)管理系統(tǒng),用固定長度的記錄大小乘以記錄號(hào)便據(jù)管理系統(tǒng),用固定長度的記錄大小乘以記錄號(hào)便得到相對于文件末尾的字節(jié)位置,
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫網(wǎng)僅提供信息存儲(chǔ)空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負(fù)責(zé)。
- 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 創(chuàng)新型人才引領(lǐng)鄉(xiāng)村振興的路徑探索
- 重慶市開州區(qū)鎮(zhèn)東初級中學(xué)2025屆化學(xué)九上期末達(dá)標(biāo)檢測模擬試題含解析
- 江蘇省無錫市第一女子中學(xué)2025屆九上化學(xué)期末預(yù)測試題含解析
- 山西財(cái)經(jīng)大學(xué)華商學(xué)院《內(nèi)部控制制度》2023-2024學(xué)年第一學(xué)期期末試卷
- 商業(yè)停車場車位租賃與廣告合作合同
- 文化教育設(shè)施設(shè)計(jì)與施工方案研究
- 2025至2030中國狗肉行業(yè)發(fā)展趨勢分析與未來投資戰(zhàn)略咨詢研究報(bào)告
- 2025至2030中國月子中心行業(yè)產(chǎn)業(yè)運(yùn)行態(tài)勢及投資規(guī)劃深度研究報(bào)告
- 石油化工行業(yè)發(fā)展現(xiàn)狀與未來趨勢分析預(yù)測報(bào)告
- 2025至2030中國自助點(diǎn)菜亭行業(yè)市場深度研究及發(fā)展前景投資可行性分析報(bào)告
- 電梯操作證及電梯維修人員資格(特種作業(yè))考試題及答案
- 2024廣西專業(yè)技術(shù)人員繼續(xù)教育公需科目參考答案(100分)
- 濟(jì)寧市消毒與醫(yī)院感染技能競賽題庫
- 2024年上海市中考語文備考之150個(gè)文言實(shí)詞刷題表格及答案
- 2023-6新高考語文答題卡(全國甲卷兩欄)可以編輯
- 校本研修活動(dòng)方案設(shè)計(jì)與實(shí)施
- 大學(xué)生心理健康教育(周莉第四版) 課件 第1-5章 主動(dòng)掌控:打造健康生活-戀愛與性:理解親密關(guān)系
- 家庭教育學(xué)整套課件
- 營銷人員財(cái)務(wù)必備之財(cái)務(wù)與營銷結(jié)合
- 2024年風(fēng)機(jī)市場洞察報(bào)告
- 鍛壓設(shè)備安裝工程施工及驗(yàn)收規(guī)范
評論
0/150
提交評論