【計算機課件】第十七章文件處理_第1頁
【計算機課件】第十七章文件處理_第2頁
【計算機課件】第十七章文件處理_第3頁
【計算機課件】第十七章文件處理_第4頁
【計算機課件】第十七章文件處理_第5頁
已閱讀5頁,還剩45頁未讀, 繼續(xù)免費閱讀

下載本文檔

版權說明:本文檔由用戶提供并上傳,收益歸屬內容提供方,若內容存在侵權,請進行舉報或認領

文檔簡介

《程序設計》2007.9

第17章文件處理

A文件中的數(shù)據(jù)層次、

?文件和流

?順序訪問文件

?隨機訪問文件

?實例:事務處理程序

?對象的輸入輸出

?小結

程序設計-1

《程序設計》2007.9

文件

?臨時數(shù)據(jù)

?存儲在變量利數(shù)組中的數(shù)據(jù)是臨時的(內存),

這些數(shù)據(jù)在程序運行結束后都會消失。,

?文件

A目的:文件用來永久地保存大量的數(shù)據(jù)。

?存儲:計算機把文件存儲在二級存儲設備

中(特別是磁盤存儲設備)。

程序設計-2

《程序設計》2007.9

數(shù)據(jù)的層次

位(bit):

>最小數(shù)據(jù)項:0和1

字符(character)/字節(jié)(byte)文件

>字符:數(shù)字、字母和專門的符號

>字節(jié):由0、1組成的序列(常見的是8位/字節(jié))

>字符用字節(jié)表示

域(field):

>一組有意義的字符,例如姓名

記錄(record)

>一組相關的域

A

>記錄關鍵字(recordkey):用于檢索

文件(Ele)Judy域

>一組相關的記錄

數(shù)據(jù)庫01001010字節(jié)(ASCII字符J)

>一組相關的文件

1位

程序設計-3

《程序設計》2007.9

舉例

。域與記錄:記錄是由多個域構成。例如,在一張工資表中,為

某個特定雇員建立的一條記錄可能是由如下域組成的:

1.雇員標識號\

2.名字\

3.地址

4.每小時工資等級

5.免稅申請?zhí)朶

6.年度收入

7.聯(lián)邦稅收額等等

文件:某個公司的工資表文件通常包含為每一個雇員建立的t4

錄。較小公司的工資表文件可能只包含22條記錄,而大型公司

的工資表文件可能要包含100000條記錄。一個機構可能建立成

百上千個文件,而每一個文件又包含幾百萬甚至幾十億個字符

信息。

程序設計-4

《程序設計》2007.9

文件中記錄的組織方式

?文件中記錄常見的兩種組織方式

>順序訪問文件(sequentialaccessfile):

?按記錄關鍵字字段的順序存儲記錄余

?例:在工資表文件中,記錄通常按

的順序存儲與訪問。

>隨機訪問文件(randomaccessfile)

?按隨機順序訪問存儲記錄的文件。

程序設計-5

《程序設計》2007.9

第17章文件處理

A文件中的數(shù)據(jù)層次、

O文件和流

?順序訪問文件

?隨機訪問文件I

A實例:事務處理程序I

?對象的輸入輸出|

?小結|■

程序設J-6

《程序設計》2007.9

文件和流

C++語言把每一個文件都看成一個字節(jié)

流(把文件看成n個字節(jié))

>每一個文件或者以文件結束符(end-of-file/EOF)結

束,或者在特定的字節(jié)號處結束。

>當打開一個文件時,該文件就和某個流關聯(lián)起來。

0__Z34J__789…n-1

...文件結束符

程序設計-7

《程序設計》2007.9

ifstream,fstream,ofstream

頭文件<iostream>和<fstream>

ios

istreamostream

ifstreamiostreamofstream

fstream

程序設計-8

《程序設計》2007.9

第17章文件處理

?文件中的數(shù)據(jù)層次、

A文件和流

A順序訪問文件

?隨機訪問文件I

A實例:事務處理程序I

?對象的輸入輸出|.

?小結|1

程序設J-9

《程序設計》2007.9

建立順序訪問文件

?C++把文件看作是無結構的字節(jié)流

?記錄的說法在C++文件中是不存在的。

程序員必須提供滿足特定應用程序要求

的文件結構。

?:?問題:怎樣給文件強加一個記錄結構?

程序設計-10

Jkl《程序設計》2007.9

例子(Fig17_04)

#include<iostream>

#include<fstream>

#include<cstdlib>

usingnamespacestd;

intmain()

(

ofstreamoutClientFile(nclients.dat0,ios::out);

if(outClientFile){//overloaded!operator

cerr?”Filecouldnotbeopened0?endl;

exit(1);//incstdlib

}

程序設計-11

《程序設計》2007.9

例子(Fig17_04續(xù))

cout?”Entertheaccount,name,andbalanceAn^

?“Enterend-of-filetoendinput.\n?

intaccount;

charname[30];

doublebalance;

while(cin?account?name?balance){

outClientFile?account?11?name

vv''vvbalance?endl;

cout?''?

return0;//ofstreamdestructorclosesfile

程序設計-12

《程序設計》2007.9

例子(續(xù))

?:?輸出結果:

Entertheaccount,name,andbalance.

Enterend-of-filetoendinput.

?100Jones24.98

?200Doe345.67

?300White0

?400Stone-42.16

?500Rich224.62

?Az

程序設計-13

豳輸入流(cin)的流狀態(tài)?

?failbit

當流中發(fā)生格式錯誤時,設置failbit,但字符并末丟失。

cin.fail()判斷流操作是否失敗,這種錯誤通??尚迯?。

badbit

當發(fā)生導致數(shù)據(jù)丟失的錯誤時,設置badbit。dn.badO判

斷流操作是否失敗,這種嚴重錯誤通常不可修復。

eofbit

如果cin遇至!J了文件結束符,設置badbit。cin.eof()

判斷eofbit是否被設置。

goodbit

如果eofbit、failbit或badbit都沒有設置,則設置goodbit。

cin.good。判斷goodbit是否被設置。

程序設計-14

《程序設計》2007.9

輸入流(cin)的流狀態(tài)

?cin.rdstate()返回流的錯誤狀態(tài)。

0:沒有錯\

非0:有錯\一

cin.clearO把一個流的狀態(tài)恢復為“好”,從而可以

對該流繼續(xù)執(zhí)行I/O操作。

?cin.ignore:在需要時跳過流中指定數(shù)量的字符(默認

個數(shù)是1),或在遇到指定的分隔符(默認分隔符是EOF,

使得ignore在讀文件的時候跳過文件末尾)時結束。

cin.ignore(10007\n,);

程序設計-15

intmain()

Fig15_22(P594)2007.9

cout?”Beforeabadinputoperation:11

?n\ncin.rdstate():“?cin.rdstate()

?n\ncin.eof():n?cin.eof()

?n\ncin.fail():"?cin.fail()

?n\ncin.bad():“?cin.bad()

?”\ncin.good():n?cin.good()

?H\n\nExpectsaninteger,butenteracharacter:n;

cin?x;

cout?n\nEnterabadinputoperation:11

?“\ncin.rdstate():n?cin.rdstate()

?n\ncin.eof():n?cin.eof()

?n\ncin.fail():''?cin.fail()

?n\ncin.bad():n?cin.bad()

?n\ncin.good()''?cin.good()?n\n\nn;

cin.clear();

cout?HAftercin.clear。"

?n\ncin.fail():n?cin.fail()

?“\ncin.good():H?cin.good()?endl;

return0;}計-16

constintMAXLEN=1000;

intget_NonNegtiveNumber()

(~獲取一個非負整數(shù)

intnumber=-1;1如果輸入的不是數(shù)字,提示重新輸入;

do2如果輸入的是浮點數(shù),例如5.6,會獲得

{一個整數(shù)5,同時清除輸入緩存區(qū),不影響

while(1)下次的cin操作

(

cin?number;

if(!cin)//沒有獲得一個int

(

number=-1;

cout?"Pleaseinputanon-negativeinteger(>=0)?endl;

break;

}

if(number>=0)break;

cout?"Pleaseinputanon-negativeinteger(>=0)?endl;

)

cin.clear();〃恢復輸入狀態(tài)信息

cin.ignore(MAXLEN,t\n,);〃清除輸入緩存區(qū)

}while(number==-1);

returnnumber;

)

《程序設計》2007.9

例子(續(xù))

?ofstreamoutClientFile("clients.dat",ios::out);

已存在的文件用ios::out打開時,文件中的所有數(shù)據(jù)均刪除。如果指

定文件還不存在,則用該文件名生成這個文件。

文件打開方式說明

ios::app將所有輸出寫入文件末尾(不修改文件中現(xiàn)有的

數(shù)據(jù))

ios::ate打開文件以便輸出,并移到文件末尾

數(shù)據(jù)可以寫入文件中的任何地方

ios::in打開文件以便輸入

ios::out打開文件以便輸出

ios::trunc刪除文件現(xiàn)有內容(是ios::out的默認操作)

程序設計-18

《程序設計》2007.9

打開與關閉文件

*打開文件(三種方式):

方式1:ofstreamoutClientFile("clients.datn,ios::out);

方式2:ofstreamoutClientFile(£clients.dat,5);

方式3:ofstreamoutClientFile;

outClientFile.open("clients.dat”,ios::out);

關閉文件(兩種方式):

方式1:main終止時,outClientFile的解析函數(shù)會關閉文件。

方式2:顯式方式:outClientFile.close();

程序設計-19

《程序設計》2007.9

測試文件打開是否成功

?用重載的ios運算符成員函數(shù)operator!確定打開操作是

否成功。如果open操作的流將failbit或badbit設置,則

這個條件返回非0值(true)??赡艿腻e誤是:

>試圖打開讀取不存在的文件\

>試圖打開讀取沒有權限的文件

>試圖打開文件以便寫入而磁盤空間不足。

程序設計-20

《程序設計》2007.9

測試文件結束符與不合法輸入

?另一人重載的ios運算符成員函數(shù)operatorvoid*將流

變成指針,使其測試為0(空指針)或非0(任何其他指針

值)。如果failbit或badbit(見第15章)對流進行設置,

則返回O(false)。

?下列while首部的條件自動調用operatorvoid*成員函

數(shù):

Line36:while(cin?account?name?balance)

只要cin的failbit和badbit都沒有設置,則條件保持true。

輸入文件結束符設置cin的failbitooperatorvoid*函數(shù)

可以側試輸入對象的文件結束符,而不必對輸入對象

顯同曲用eof成員函數(shù)。

程序設計-21

《程序設計》2007.9

讀取順序訪問文件中的數(shù)據(jù)

?讀取文件(三種方式)

方式1:ifstreaminClientFile(uclients.datJ\ios::in);

方式2:ifstreaminClientFile(uclients.dat,J);

方式3:ifstreaminClientFile;

inClientFile.open(uclients.dat,J,ios::in);

程序設計-22

駕《程序設計》2007.9

1例子(Fig17_07)

#include<iostreamo>

#include<fstream>

#include<iomanip>

#include<string>

#include<cstdlib>

voidoutputLine(int,conststring,double);

intmain()

(

//ifstreamconstructoropensthefile

ifstreaminClientFile(nclients.datu,ios::in);

if(inClientFile){

cerr?"Filecouldnotbeopened\nu;

exit(1);

)

程序設計-23

《程序設計》2007.9

■例子(續(xù))

intaccountt;

charname[30];

doublebalance;

cout?left?setw(10)?''Account"?setw(13)

?“Name"?HBalance,,?endl?fixed?showpoint;

while(inClientFile?account?name?balance)

outputLine(account,name,balance);

return0;//ifstreamdestructorclosesthefile

)

voidoutputLine(intaccount,conststringname,doublebalance)

(

cout?left?setw(10)?account?setw(13)?name

?setw(7)?setprecision(2)?right?balance?endl;

}

程序設計-24

《程序設計》2007.9

例子(續(xù))

輸出結果:

AccountNam一Balance

100Jonas24.98

200D。一345.67

300Whit一0.00

400Stem一-42.16

500Rich224.62

程序設計-25

文件位置指針及其重新定檢39

文件位置指針(,lepositionpointer):用于指示讀寫操作所在的下一

個字節(jié)號;是個整砥(值,語定文件中離文件開頭的相對位置(也稱為

離文件開頭的偏移量)。'

重新定位

>istream類的(long,參數(shù)2):每個istream對象有個get指針,表示

文件中下一個輸入相距的字節(jié)數(shù)。

seekg的第一個參數(shù)通常為long類型的整數(shù);

第二個參數(shù)可以指定尋找方向:

?ios::beg(默認)相對于流的開頭定位

?ios::curj目對手流當前位置定位

?ios::end相對于流結尾定位。

>ostream類的(即“seekput"):每個ostream對象有一個put指針,

表示文件中下一個輸出相距的學節(jié)數(shù)。

例子:inclientFile.§eekg(0);

將文件位置指針移薊文徉開頭(位置0),連接inclientFile。

程序設計-26

文件位置指針的例子-9

。下面是一些get文件位置指針的例子:

//positiontothenthbyteofflleObject

//assumesios::beg

fileObject.seekg(n);

//positionnbytesforwardinflleObject

fileObject.seekg(n,ios::cur);

//positionybytesbackfromendofflleObject

fileObject.seekg(y,ios::end);

//positionatendofflleObject

fileObject.seekg(0,ios::end);

ostream成員函數(shù)seekp也可以進行類似的操作。

成員函數(shù)tellg和tellp分別返回get和put指針的當前位置

location=filObject.tellgO;

程序設計-27

更新順序訪問文件《程序設計》2007.9

?:?格式化和寫入順序訪問文件的數(shù)據(jù)修改時會有破壞文件

中其他數(shù)據(jù)的危險

?例如,如果要把名字“White”改為“Worthington”,

White的原來的記錄是:300White0.00

修改后:300Worthington0.00

出現(xiàn)該問題的原因在于:在使用流插入運算符《和流讀

取運算符>>的格式化輸入,輸出模型中,域的大小是不

定的,因而記錄的大小也是不定的。

例如,7、14、-117、2047和27383都是int類型的值,雖然

它們的內部存儲占用相同的字節(jié)數(shù),因此,格式化輸入,

輸出模型通常不用來更新已有的記錄。

程序設計-28

《程序設計》2007.9

更新順序訪問文件(續(xù))

?一種解決方法(但比較危險):

1:將在300White0.00之前的記錄復制到

一個新的文件中

2:然后寫入新的記錄并把300White0.00

之后的記錄復制到新文件中。

程序設計-29

《程序設計》2007.9

第17章文件處理

?文件中的數(shù)據(jù)層出、

?文件和流

?順序訪問文件

A隨機訪問文件

?實例:事務處理程序|

?對象的輸入輸出|\

?小結|1

程序設計-30

《程序設計》2007.9

隨機訪問文件

?順序訪問文件不適合快速訪問應用程序,即要立即找

到特定記錄的信息。\

*快速訪問應用程序的例子有航空訂票系統(tǒng)、銀行系統(tǒng)、

第售網(wǎng)點系統(tǒng)、自動柜員機和其他要求快速處理特定

數(shù)據(jù)的事務處理系統(tǒng)(transactionprocessingsystem)o

銀行要面對成千上萬的客戶,但自動柜員機能在瞬間

作出響應。這種快速訪問應用程序是用隨機訪問文件

(randomaccessfile)實壬見的。

隨機訪問文件的各個記錄可以直接快速訪問,而不需

要進行搜索。

程序設計-31

《程序設計》2007.9

使用定長記錄的隨機訪問文件

?C++不提供文件結構。因此應用程序要自己生成隨機

訪問文件。雖然實現(xiàn)隨機訪問文件還有其他方法,但

是本課程的討論只限于使用定長記錄的這種簡潔明了

的方法。

?因為隨機訪問文件中的每一條記錄都有相同的長度,

所以能夠用記錄關鍵字的函數(shù)計算出每一條記錄相對

于文件起始點的位置。

將學到:怎樣立即訪問到文件甚至大型文件中指定的

>可以在不破壞其他數(shù)據(jù)的情況下把數(shù)據(jù)插入到隨機訪問文件

中。

>也能在不重寫整個文件的情況下更新和刪除以前存儲的數(shù)據(jù)。

>怎擇建立隨機訪問文件、鍵入數(shù)據(jù)、順序和隨機地讀取數(shù)據(jù)、

更新藪據(jù)和刪除不再需要的數(shù)據(jù)。

程序設計-32

《程序設計》2007.9

整數(shù)寫入文件(固定占4個字節(jié))

?outFile?number;

貝U對4字節(jié)整數(shù)占1?11字節(jié)(10位數(shù)加"符號位)

改用:

outFile.(reinterpret_cast<constchar*>(&number),

sizeof(number));

>這種方法總是寫入4字節(jié)(在4字節(jié)整數(shù)機器上)。\

>用reinterpret_castvconstchar*>強制類型轉換運算符將number的地址

變?yōu)閏onstchar*指針。\

>write的第二個參數(shù)是sizet類型的整數(shù),指定寫入的字節(jié)數(shù)

*istream函數(shù)可以將4個字節(jié)讀回到整型變量number中。

*隨機存取文件處理程序很少只把一個域寫入文件中,通常會

一次寫入一個結構或一個類對象。

程序設計-33

《程序設計》2007.9

例子

建立一個能夠存儲100個定長記錄的借貸

處理系統(tǒng):

1、每一條記錄由賬號(用作記錄關鍵字卜,

姓、名和借貸金額組成。

2、程序要能夠更新、插入和刪除一條記

錄以及能夠以格式化文本形式列出所有

的記錄。\

3、要求使用隨機訪問文件?!?/p>

程序設計-34

例子:順序生成隨機訪問文侏一

(Fig17_10)

#ifndefCLIENTDATAH

#defineCLNTDATAH

classClientData{

public:

ClientData(int=O;string='"'double=0);

private:

intaccountNumber;

charlastName[15];

charfirstName[10];

floatbalance;

};

#endif

程序設計-35

《程序設計》2007.9

例子:順序生成隨機訪問文件(續(xù))

intmain()

ofstreamoutCredit(ncredit.datn,ios::binary);

if(loutCredit){

cerr?”Filecouldnotbeopened."?endl;

exit(1);

}

clientDatablankClient;

for(inti=0;i<100;i++)

outCredit.write(

reinterpret_cast<constchar*>(&blankClient),

sizeof(clientData));

return0;

程序設計-36

例子:隨機地寫入隨機訪問蝴小

(Fig17_13)

intmain()

intaccountNumber;

charlastName[15];

charfirstName[10];

doublebalance;

ofstreamoutCredit(ncredit.datn,ios:in|ios::out:ios::binary);

if(!outCredit){

cerr?"Filecouldnotbeopened/1?endl;

exit(1);

cout?”Enteraccountnumber”

?n(lto100,0toendinput)\n?n;

clientDataclient;

cin?accountNumber;程序設計-37

子:隨機地寫入隨機訪問文件幺續(xù)黑9

f(Fig17_13)

while(accountNumber>0&accountNumber<=100){

cout?"Enterlastname,firstname,balance\n?

cin?setw(15)?lastName;

cin?setw(10)?firstName;

cin?balance;

client.setAccountNumber(accountNumber);

■■■

outCreditseekp((client.accountNumber-1)*sizeof(clientData));

outCredit.write(

reinterpret_cast<constchar*>(&client),sizeof(clientData));

cout?”Enteraccountnumber\n?”;

cin?accountNumber;

return0;

程序設計-38

《程序設計》2007.9

例子:隨機地寫入隨機訪問文件(續(xù))

Enteraccountnumber(1to100,0toendinput)

?37

Enterlastname,firstname,balance

?BarkerDoug0.00

Enteraccountnumber

?29

Enterlastname,firstname,balance

?BarkerNancy-24.54

Enteraccountnumber

?96

Enterlastname,firstname,balance

?StoneSam34.98

Enteraccountnumber

?88

Enterlastname,firstname,balance

?SmithDave258.34

Enteraccountnumber

?33

Enterlastname,firstname,balance

?DunnStacey314.33

Enteraccountnumber

?0

程序設計-39

子:從隨機訪問文件中順序地《數(shù)據(jù)2g9

(Fig17_14)

voidoutputLine(ostream<&,constclientData&);

intmain()

ifstreaminCredit(ncredit.dat);

if(!inCredit){

cerr?"Filecouldnotbeopened.0?endl;

exit(1);

cout?left?setw(10)?”Account"?setw(16)

?“LastName"?setw(11)?nfirstName"?left

?setw(10)?right〈〈''Balance''?endl;

程序設計-40

目例子:從隨機訪問文件中順序地讀取數(shù)據(jù)^續(xù)2r9

(Fig17_14)

clientDataclient;

inCredit.(reinterpret_cast<char*>(&client),sizeof(clientData));

while(inCredit&&!inCredit.eof())

(

if(client.getAccountNumber!=0)

outputLine(cout,client);

inCredit.read(reinterpret_cast<char*>(&client),

sizeof(clientData));

}

return0;

}

程序設計-41

《程序設計》2007.9

Hi

例子:從隨機訪問文件中順序地讀取數(shù)據(jù)(續(xù))

輸出結果:

AccountLastNameFirstNameBalance

29BrownNancy-24.54

33DunnStacey319.33

37BarkerDoug9.00

88SmithDave258.34

96StoneSam34.98

程序設計-42

《程序設計》2007.9

第14章文件處理

A文件中的數(shù)據(jù)層次、

A文件和流

A順序訪問文件

A隨機訪問文件I

A實例:事務處理程序|

?對象的輸入輸出|.

?小結|

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內容里面會有圖紙預覽,若沒有圖紙預覽就沒有圖紙。
  • 4. 未經權益所有人同意不得將文件中的內容挪作商業(yè)或盈利用途。
  • 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內容的表現(xiàn)方式做保護處理,對用戶上傳分享的文檔內容本身不做任何修改或編輯,并不能對任何下載內容負責。
  • 6. 下載文件中如有侵權或不適當內容,請與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

最新文檔

評論

0/150

提交評論