下载本文档
版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
1、c+文件流存取结构体数组操作实例及解析前面已经介绍,二进制文件不是以ascii代码存放数据的,它将内存中数据存储形式不加转换地传送到磁盘文件,因此它又称为内存数据的映像文件。由于文件中的信息不是字符数据,而是字节中的二进制形式的信息,因此它又称为字节文件。 对二进制文件的操作也需要先打开文件,用尽后要关闭文件。在打开时要用ios:binary指定为以二进制形式传送和存储。二进制文件除了可以作为输入文件或输出文件外,还可以是既能输入又能输出的文件。这是和ascii文件不同的地方。 1用成员函数read和读写二进制文件 对二进制文件的读写主要用eam类的成员函数read和write来实现。这两个成
2、员函数的原型为 istream read(char *buffer,inllea); ostream write(coastchar*buffer,intlen); 字符指针buffer指向内存中一段存储空间。len是读写的字节数。调用的方式为 a.write(pl,50); b.read(p2,30); 上面第一行中的a是输出文件流对象,wrtte函数将字符指针pl所给出的地址开头的50个字节的内容不加转换地写到磁盘文件中。在其次行中,b是输入文件流对象,read函数从b所关联的磁盘文件中,读人30个字节(或遇eof结束),存放在字符指针p2所指的一段空间内。 例14 将一批数据以二进制形式
3、存放在磁盘文件中。 可以写出下面的程序: ilude fstream using namespace std; struct student char name20; int num; int age; char s; ; int main() student stud3= li ,1001,18, f , fun ,1002,19, m , wang ,1004,17, f ofstream out( stud.dat ,ios:binary); if(!outfile) cerr open error! endl; abort(); /退出程序 for(int i=0;i i+) outf
4、ile.write(char *) studi,sizeof(studi); outfile.close(); return 0; 定义了结构体类型student,它包括4个成员。用student定义结构体数组stud,并对其初始化。建立输出文件流对象outfile,打开磁盘文件stud.dat(假如本来无此文件,则建立新文件,假如已有同名文件则将其原有内容删除,以便重新写人数据)。将stud.dat文件的工作方式定为二进制文件。 用成员函数write向stud.dat输出数据,先前面给出的write函数的原型可以看出:第1个形参是指向char型常变量的指针变量buffer,之所以用const
5、声明,是由于不允许通过指针转变其指向数据的值。形参要求相应的实参是字符指针或字符串的首地址。现在要将结构体数组的一个元素(包含4个成员)一次输到磁盘文件stud.dat。 studi是结构体数组第i个元素的首地址,但这是指向结构体的指针,与形参类型不匹配。因此要用(char。)把它强制转换为字符指针。第2个参数是指定一次输出的字节数。sizeof (studi)的值是结构体数组的一个元素的字节数。调用一次write函数,就将从 stud 开头的结构体数组的一个元素输出到磁盘文件中,执行3次循环输出结构休数组的3个元素。 其实可以一次输出结构体数组的3个元素,将for循环的两行政为以下一行: o
6、utfile.write(char*) studo,sizeof(stud); 执行一次write函数即输出了结构体数组的所有数据。 abort函数的作用是退出程序,与exit函数的作用相同。 可以看到,用这种办法一次可以输出一批数据,效率较高。在输出的数据之间不必加入空格,在一次输出之后也不必加回车换行符。在以后从该文件读人数据时不是靠空格作为数据的间隔,而是用字节数来控制。 例15 将刚才以二进制形式存放在磁盘文件中的数据读人内存并在显示器上显示。 include fstream using namespace std; struct student char name20; int nu
7、m; int age; char sex; ; int main() student stud3; int i; ifstream infile( stud.dat ,ios:binary); if(!infile) cerr open error! endl; abort(); for(i=0;i i+) infile.read(char*) studi,sizeof(studi); infile.close(); for(i=0;i i+) cout no. i+1 endl; cout name: endl; cout num: studi.num endl; co
8、ut age: studi.age endl; cout sex: studi.sex endl endl; return 0; 运行时在显示器上显示: no1 name:li num:1001 age:18 sex:t no2 name:fun num:1001 age:19 sex:m no3 name:wang num:1004 age:17 sex:t 有了例714的基础,读者看懂这个程序是不会有什么困难的。 请思量:能否 次读人文件中的所有数据,如 infileread(char*) studo,sizeof(stud); 答案是可以的,将指定数目的字节读入内存,依次存放在以地址 s
9、tud0开头的存储空间中。要注重读人的数据的格式要与存放它的空间的格式匹配。因为磁盘文件中的数据是从内存中结构体数组元素得来的,因此它仍然保留结构体元素的数据格式。现在再读人内存,存放在同样的结构体数组中,这必定是匹配的。假如把它放到一个整型数组中,就不匹配了,会出错。 2与文件指针有关的流成员函数 在磁盘文件中有一个文件指针,用来指明当前应举行读写的位置。在输入时每读人一个字节,指针就向后移动一个字节。在输出时每向文件输出一个字节,指针就向后移动一个字节,随着输出文件中字节不断增强,指针不断后移。对于二进制文件,允许对指针举行控制,使它按用户的意图移动到所需的位置,以便在该位置上举行渎写。文
10、件流提供一些有关文件指针的成员函数。为了查阅便利,将它们归纳为表7,并作须要的解释。 解释: (1)读者很简单发觉:这些函数名的第一个字母或最后一个字母不是g就是p。带g的是用于输入的函数(g是get的第一个字母,以g作为输入的标识,简单理解和记忆),带p的是用于输出的函数(p是put的第一个字母,以p作为输出的标识)。例如有两个tell函数,tellg用于输人文件,tellp用于输出文件。同样,seekg用于输入文件,seekp用于输出文件。以上函数见名知意,一看就明了,不必死记。 假如是既可输入又可输出的文件,则随意用seekg或seekp。 (2)函数参数中的 文件中的位置 和 位移量
11、已被指定为long型整数,以字节为单位。 参照位置 可以是下面三者之一: ios:beg 文件开始(beg是begin的缩写),这是默认值。 ios :cur 指针当前的位置(cur是current的缩写)。 ios :end 文件末尾。 它们是在los类中定义的枚举常量。 举例如下: infile.seekg(100); /输入文件中的指针向前移到100字节位置 infile.seekg(-50,ios:cur);/输入文件中的指针从当前位置后移50字节 outfile.seekp(-75,ios:end);/输出文件中的指针从文件尾后移50字节 3随机拜访二进制数据文件 普通状况下读写是挨
12、次举行的,即逐个字节举行渎写。但是对于二进制数据文件来说,可以利用上面的成员函数移动指针,随机地拜访文件中任一位置上的数据,还可以修改文件中的内容。 例16 有5个同学的数据,要求: (1)把它们存到磁盘文件中; (2)将磁盘文件中的第l,3,5个同学数据读人程序,并显示出来; (3)将第3个同学的数据修改后存回磁盘文件中的原有位置; (4)从磁盘文件读入修改后的5个同学的数据并显示出来。 要实现以上要求,需要解决3个问题: (1)因为同一磁盘文件在程序中需要频繁地举行输入和输出,因此可将文件的工作方式指定为输入输出文件,即ios:in|ios:out|ios:binary。 (2)正确计算好
13、每次拜访时指针的定位,即正确用法seekg或seekp函数。 (3)正确举行文件中数据的重写(更新)。 可写出以下程序: include fstream using namespace std; struct student int num; char name20; float score; ; int main() int i; student stud5=1001, li ,85,1002, fun ,97.5,1004, wang ,54, 1006, tan ,76.5,1010, ling ,96; fstream iofile( stud.dat ,ios:in|ios:out|
14、ios:binary); /用fstream类定义输入输出二进制文件流对象iofile if(!iofile) cerr open error! endl; abort(); for(i=0;i i+) /向磁盘文件输出5个同学的数据 iofile.write(char *) studi,sizeof(studi); student stud15; /用来存放从磁盘文件读入的数据 for(i=0;i i=i+2) iofile.seekg(i*sizeof(studi),ios:beg); /定位于第0,2,4同学数据开始 iofile.read(char *) stud1i/2,sizeof
15、(stud1i); /先后读人3个同学的数据,存放在studlo,stud1和stud2中 cout stud1i/2.num stud1i/2.name stud1i/2.score endl; /输出studl0,stud1)和stud2各成员的值 cout endl; stud2.num=1012; /修改第3个同学(序号为2)的数据 stry(, wu stud2.score=60; iofile.seekp(2*sizeof(stud0),ios:beg); /定位于第3个同学数据的开始 iofile.write(char *) stud2,sizeof(stud
16、2); /更新第3个同学数据 iofile.seekg(0,ios:beg); /重新定位于文件开始 for(i=0;i i+) iofile.read(char *) studi,sizeof(studi);/读入5个同学的数据 cout studi.num studi.score endl; iofile.close(); return 0; 运行状况如下: 1001 li 85 (第1个同学数据) 1004 wang 54 (第3个同学数据) 1010 ling 96 (第5个学牛数据) 1001 li 85 (输出修改后5个同学数据) 1002 fun 975 1012 wu 60 (巳修改的第3个同学数据) 1006 tan 765 1010 ling 96 本程序也可以将磁盘文件studdat先后定义为输出文件和输人文件,在结束第一次的输出之后关闭该文件,然后再按输入方式打开它,输入完后再关闭它,然后再按输出方式打开,再关闭,再按输入方式打开它,输入完后再关闭。明显这是很烦琐和不便利的。 在程序中把它指定为输入输出型的二进制文件。这样,不仅可以向文件添加新的数据或读人数据,还可以修改(更新)数据。利用这些功能,可以实现比较复杂的输入输出任务,请注重,不能用ifstream或ofstream类定义输入输出的二进制文件流对象,而应该用fstr
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 2024年高速公路ETC系统升级改造合同
- 2025年度智能物流平台合作返点合同范本4篇
- 2025年度现代农业设施承揽合同补充协议4篇
- 2025年度油气储罐安全检测与改造合同4篇
- 2025年10kv线路施工绿色环保与节能减排合同3篇
- 2025年度智能车位租赁合同转让协议书(全新版)4篇
- 2024年车辆购销合同示范文本
- 2025年度智能储煤场租赁管理服务合同4篇
- 2024矿用设备租赁合同
- 2025年度城市更新改造项目承包合同签约与历史文化保护协议(2024版)3篇
- 2024年海口市选调生考试(行政职业能力测验)综合能力测试题及答案1套
- 六年级数学质量分析及改进措施
- 一年级下册数学口算题卡打印
- 2024年中科院心理咨询师新教材各单元考试题库大全-下(多选题部分)
- 真人cs基于信号发射的激光武器设计
- 【阅读提升】部编版语文五年级下册第三单元阅读要素解析 类文阅读课外阅读过关(含答案)
- 四年级上册递等式计算练习200题及答案
- 法院后勤部门述职报告
- 2024年国信证券招聘笔试参考题库附带答案详解
- 道医馆可行性报告
- 视网膜中央静脉阻塞护理查房课件
评论
0/150
提交评论