【计算机课件】第十七章文件处理_第1页
【计算机课件】第十七章文件处理_第2页
【计算机课件】第十七章文件处理_第3页
【计算机课件】第十七章文件处理_第4页
【计算机课件】第十七章文件处理_第5页
已阅读5页,还剩45页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

《程序设计》2007.9

第17章文件处理

A文件中的数据层次、

►文件和流

►顺序访问文件

►随机访问文件

►实例:事务处理程序

►对象的输入输出

►小结

程序设计-1

《程序设计》2007.9

文件

❖临时数据

»存储在变量利数组中的数据是临时的(内存),

这些数据在程序运行结束后都会消失。,

♦文件

A目的:文件用来永久地保存大量的数据。

»存储:计算机把文件存储在二级存储设备

中(特别是磁盘存储设备)。

程序设计-2

《程序设计》2007.9

数据的层次

位(bit):

>最小数据项:0和1

字符(character)/字节(byte)文件

>字符:数字、字母和专门的符号

>字节:由0、1组成的序列(常见的是8位/字节)

>字符用字节表示

域(field):

>一组有意义的字符,例如姓名

记录(record)

>一组相关的域

A

>记录关键字(recordkey):用于检索

文件(Ele)Judy域

>一组相关的记录

数据库01001010字节(ASCII字符J)

>一组相关的文件

1位

程序设计-3

《程序设计》2007.9

举例

。域与记录:记录是由多个域构成。例如,在一张工资表中,为

某个特定雇员建立的一条记录可能是由如下域组成的:

1.雇员标识号\

2.名字\

3.地址

4.每小时工资等级

5.免税申请号\

6.年度收入

7.联邦税收额等等

文件:某个公司的工资表文件通常包含为每一个雇员建立的t4

录。较小公司的工资表文件可能只包含22条记录,而大型公司

的工资表文件可能要包含100000条记录。一个机构可能建立成

百上千个文件,而每一个文件又包含几百万甚至几十亿个字符

信息。

程序设计-4

《程序设计》2007.9

文件中记录的组织方式

❖文件中记录常见的两种组织方式

>顺序访问文件(sequentialaccessfile):

•按记录关键字字段的顺序存储记录余

•例:在工资表文件中,记录通常按

的顺序存储与访问。

>随机访问文件(randomaccessfile)

•按随机顺序访问存储记录的文件。

程序设计-5

《程序设计》2007.9

第17章文件处理

A文件中的数据层次、

O文件和流

►顺序访问文件

►随机访问文件I

A实例:事务处理程序I

►对象的输入输出|

►小结|■

程序设J-6

《程序设计》2007.9

文件和流

C++语言把每一个文件都看成一个字节

流(把文件看成n个字节)

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

束,或者在特定的字节号处结束。

>当打开一个文件时,该文件就和某个流关联起来。

0__Z34J__789…n-1

...文件结束符

程序设计-7

《程序设计》2007.9

ifstream,fstream,ofstream

头文件<iostream>和<fstream>

ios

istreamostream

ifstreamiostreamofstream

fstream

程序设计-8

《程序设计》2007.9

第17章文件处理

►文件中的数据层次、

A文件和流

A顺序访问文件

►随机访问文件I

A实例:事务处理程序I

►对象的输入输出|.

►小结|1

程序设J-9

《程序设计》2007.9

建立顺序访问文件

❖C++把文件看作是无结构的字节流

❖记录的说法在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续)

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

例子(续)

♦:♦输出结果:

Entertheaccount,name,andbalance.

Enterend-of-filetoendinput.

?100Jones24.98

?200Doe345.67

?300White0

?400Stone-42.16

?500Rich224.62

?Az

程序设计-13

豳输入流(cin)的流状态™

♦failbit

当流中发生格式错误时,设置failbit,但字符并末丢失。

cin.fail()判断流操作是否失败,这种错误通常可修复。

badbit

当发生导致数据丢失的错误时,设置badbit。dn.badO判

断流操作是否失败,这种严重错误通常不可修复。

eofbit

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

判断eofbit是否被设置。

goodbit

如果eofbit、failbit或badbit都没有设置,则设置goodbit。

cin.good。判断goodbit是否被设置。

程序设计-14

《程序设计》2007.9

输入流(cin)的流状态

♦cin.rdstate()返回流的错误状态。

0:没有错\

非0:有错\一

cin.clearO把一个流的状态恢复为“好”,从而可以

对该流继续执行I/O操作。

♦cin.ignore:在需要时跳过流中指定数量的字符(默认

个数是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()

(~获取一个非负整数

intnumber=-1;1如果输入的不是数字,提示重新输入;

do2如果输入的是浮点数,例如5.6,会获得

{一个整数5,同时清除输入缓存区,不影响

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();〃恢复输入状态信息

cin.ignore(MAXLEN,t\n,);〃清除输入缓存区

}while(number==-1);

returnnumber;

)

《程序设计》2007.9

例子(续)

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

已存在的文件用ios::out打开时,文件中的所有数据均删除。如果指

定文件还不存在,则用该文件名生成这个文件。

文件打开方式说明

ios::app将所有输出写入文件末尾(不修改文件中现有的

数据)

ios::ate打开文件以便输出,并移到文件末尾

数据可以写入文件中的任何地方

ios::in打开文件以便输入

ios::out打开文件以便输出

ios::trunc删除文件现有内容(是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的解析函数会关闭文件。

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

程序设计-19

《程序设计》2007.9

测试文件打开是否成功

♦用重载的ios运算符成员函数operator!确定打开操作是

否成功。如果open操作的流将failbit或badbit设置,则

这个条件返回非0值(true)。可能的错误是:

>试图打开读取不存在的文件\

>试图打开读取没有权限的文件

>试图打开文件以便写入而磁盘空间不足。

程序设计-20

《程序设计》2007.9

测试文件结束符与不合法输入

♦另一人重载的ios运算符成员函数operatorvoid*将流

变成指针,使其测试为0(空指针)或非0(任何其他指针

值)。如果failbit或badbit(见第15章)对流进行设置,

则返回O(false)。

♦下列while首部的条件自动调用operatorvoid*成员函

数:

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

只要cin的failbit和badbit都没有设置,则条件保持true。

输入文件结束符设置cin的failbitooperatorvoid*函数

可以侧试输入对象的文件结束符,而不必对输入对象

显同曲用eof成员函数。

程序设计-21

《程序设计》2007.9

读取顺序访问文件中的数据

❖读取文件(三种方式)

方式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

■例子(续)

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

例子(续)

输出结果:

AccountNam㊀Balance

100Jonas24.98

200D。㊀345.67

300Whit㊀0.00

400Stem㊀-42.16

500Rich224.62

程序设计-25

文件位置指针及其重新定检39

文件位置指针(,lepositionpointer):用于指示读写操作所在的下一

个字节号;是个整砥(值,语定文件中离文件开头的相对位置(也称为

离文件开头的偏移量)。'

重新定位

>istream类的(long,参数2):每个istream对象有个get指针,表示

文件中下一个输入相距的字节数。

seekg的第一个参数通常为long类型的整数;

第二个参数可以指定寻找方向:

•ios::beg(默认)相对于流的开头定位

•ios::curj目对手流当前位置定位

•ios::end相对于流结尾定位。

>ostream类的(即“seekput"):每个ostream对象有一个put指针,

表示文件中下一个输出相距的学节数。

例子: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成员函数seekp也可以进行类似的操作。

成员函数tellg和tellp分别返回get和put指针的当前位置

location=filObject.tellgO;

程序设计-27

更新顺序访问文件《程序设计》2007.9

♦:♦格式化和写入顺序访问文件的数据修改时会有破坏文件

中其他数据的危险

❖例如,如果要把名字“White”改为“Worthington”,

White的原来的记录是:300White0.00

修改后:300Worthington0.00

出现该问题的原因在于:在使用流插入运算符《和流读

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

定的,因而记录的大小也是不定的。

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

它们的内部存储占用相同的字节数,因此,格式化输入,

输出模型通常不用来更新已有的记录。

程序设计-28

《程序设计》2007.9

更新顺序访问文件(续)

❖一种解决方法(但比较危险):

1:将在300White0.00之前的记录复制到

一个新的文件中

2:然后写入新的记录并把300White0.00

之后的记录复制到新文件中。

程序设计-29

《程序设计》2007.9

第17章文件处理

►文件中的数据层出、

►文件和流

►顺序访问文件

A随机访问文件

►实例:事务处理程序|

►对象的输入输出|\

►小结|1

程序设计-30

《程序设计》2007.9

随机访问文件

♦顺序访问文件不适合快速访问应用程序,即要立即找

到特定记录的信息。\

*快速访问应用程序的例子有航空订票系统、银行系统、

第售网点系统、自动柜员机和其他要求快速处理特定

数据的事务处理系统(transactionprocessingsystem)o

银行要面对成千上万的客户,但自动柜员机能在瞬间

作出响应。这种快速访问应用程序是用随机访问文件

(randomaccessfile)实壬见的。

随机访问文件的各个记录可以直接快速访问,而不需

要进行搜索。

程序设计-31

《程序设计》2007.9

使用定长记录的随机访问文件

♦C++不提供文件结构。因此应用程序要自己生成随机

访问文件。虽然实现随机访问文件还有其他方法,但

是本课程的讨论只限于使用定长记录的这种简洁明了

的方法。

♦因为随机访问文件中的每一条记录都有相同的长度,

所以能够用记录关键字的函数计算出每一条记录相对

于文件起始点的位置。

将学到:怎样立即访问到文件甚至大型文件中指定的

>可以在不破坏其他数据的情况下把数据插入到随机访问文件

中。

>也能在不重写整个文件的情况下更新和删除以前存储的数据。

>怎择建立随机访问文件、键入数据、顺序和随机地读取数据、

更新薮据和删除不再需要的数据。

程序设计-32

《程序设计》2007.9

整数写入文件(固定占4个字节)

♦outFile«number;

贝U对4字节整数占1〜11字节(10位数加"符号位)

改用:

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

sizeof(number));

>这种方法总是写入4字节(在4字节整数机器上)。\

>用reinterpret_castvconstchar*>强制类型转换运算符将number的地址

变为constchar*指针。\

>write的第二个参数是sizet类型的整数,指定写入的字节数

*istream函数可以将4个字节读回到整型变量number中。

*随机存取文件处理程序很少只把一个域写入文件中,通常会

一次写入一个结构或一个类对象。

程序设计-33

《程序设计》2007.9

例子

建立一个能够存储100个定长记录的借贷

处理系统:

1、每一条记录由账号(用作记录关键字卜,

姓、名和借贷金额组成。

2、程序要能够更新、插入和删除一条记

录以及能够以格式化文本形式列出所有

的记录。\

3、要求使用随机访问文件。■

程序设计-34

例子:顺序生成随机访问文侏一

(Fig17_10)

#ifndefCLIENTDATAH

#defineCLNTDATAH

classClientData{

public:

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

private:

intaccountNumber;

charlastName[15];

charfirstName[10];

floatbalance;

};

#endif

程序设计-35

《程序设计》2007.9

例子:顺序生成随机访问文件(续)

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

子:随机地写入随机访问文件幺续黑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

例子:随机地写入随机访问文件(续)

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

子:从随机访问文件中顺序地《数据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

目例子:从随机访问文件中顺序地读取数据^续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

例子:从随机访问文件中顺序地读取数据(续)

输出结果:

AccountLastNameFirstNameBalance

29BrownNancy-24.54

33DunnStacey319.33

37BarkerDoug9.00

88SmithDave258.34

96StoneSam34.98

程序设计-42

《程序设计》2007.9

第14章文件处理

A文件中的数据层次、

A文件和流

A顺序访问文件

A随机访问文件I

A实例:事务处理程序|

►对象的输入输出|.

►小结|

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论