第10章 输入输出流NEW(夏老师)_第1页
第10章 输入输出流NEW(夏老师)_第2页
第10章 输入输出流NEW(夏老师)_第3页
第10章 输入输出流NEW(夏老师)_第4页
第10章 输入输出流NEW(夏老师)_第5页
已阅读5页,还剩65页未读 继续免费阅读

下载本文档

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

文档简介

1、第10章 输入输出流 10.1 文件概述补充 文件有不同类型,在程序设计中主要用到两种文件: (1)程序文件: 包括源程序文件(后缀.cpp)、目标文件(后 缀.obj)、可执行文件(后缀.exe) (2)数据文件 文件的内容不是程序,而是供程序运行时读写的 数据。 本章主要讨论数据文件 所谓“数据文件数据文件”一般指存储在外部介质 上数据的集合。操作系统以文件为单位进行管 理。 输入输出是数据的传输过程,数据如流水 一样从一处流向另一处,因此常将输入输出形 象地称为流stream,即数据流 10.1.1 文件名 一个文件要有一个唯一的文件标识,以便用 户识别和引用。文件标识包括三部分:(1)

2、 文件 路径;(2)文件名主干;(3)文件名后缀 。 d:userfile1.dat “d:userfile1.dat” 程序中用字符串表示为: 10.1.2 文件的分类 根据数据的组织形式,数据文件可以分为ASCII文件和 二进制文件。 记住:数据在内存中是以二进制形式存储的记住:数据在内存中是以二进制形式存储的 二进制文件二进制文件:如果内存中的数据不加转换地输出到外 存,就是二进制文件,可以认为它是存储在内存中的 数据的映像,所以也称之为映像文件(image file)。 ASCII文件文件 :如果内存中的数据转换成ASCII代码 后输出到文件,就是ASCII文件。 ACSII文件又称文

3、本文件(text file),每一个字节放 一个字符的ASII码。 数据在二进制文件与数据在二进制文件与ASCII文件中存储方式?文件中存储方式? 字符一律以ASCII形式存储,数值型数 据可以用ASCII码形式存储,也可用二进制形 式存储。如整数10000,用ASCII码形式输出 到磁盘,则在磁盘中占5个字节(每一个字符 占一个字节),而用二进制形式存储,则在磁 盘上占4个字节(用Visual C+时)。 00000000000000000010011100010000内存存储形式:内存存储形式:10000 00000000000000000010011100010000写入二进制文件写入二

4、进制文件 写入文本数据文件写入文本数据文件 0011000100110000001100000011000000110000 1的ASII码490的ASII码48 10.1.3 文件缓冲区 ASCII标准采用“缓冲文件系统”处理数 据文件,所谓缓冲文件系统缓冲文件系统是指系统自动地在 内存区为程序中每一个正在使用的文件开辟一 个文件缓冲区。从内存向磁盘输出数据必须先 送到内存中的文件缓冲区,装满缓冲区后才一 起送到磁盘去;反过来,如果计算机从磁盘读 入数据,则一次从磁盘文件将一批数据读入到 文件缓冲区(充满缓冲区),然后再从缓冲区 将数据逐一送到程序数据区(给程序中的变 量)。 输出文件缓冲区

5、 输入文件缓冲区 程序数据区 磁盘 输入 输出 10.2 I/O流 C+的输入输出是以流(字节序列)的形式进行的 。 C+的输入输出主要有以下两种: o 对系统指定的标准设备的输入输出,即标准标准I/O。 o 以外存磁盘文件为对象进行的输入输出,称为文件文件I/O 10.2.1 流的分类 程序 标准I/O文件I/O 输出 输入 输入 输出 n cin是类istream内置的标准流类对象,能 构成从键盘到内存的标准输入流。 n cout是类istream内置的标准流类对象,能 构成从内存到屏幕的标准输出流。 10.2.2 流对象 (1)标准流对象 (2)文件流对象 n 文件流对象构成内存到文件的

6、输入输出流。从 文件中读取数据到内存,称为文件输入流;从 内存数据写入到文件,称为文件输出流。 1标准I/O流类库 (1)基类ios (2)输入类istream (3)输出类ostream (4)输入输出类iostream 2文件I/O流类库 (1)ofstream类 (2)ifstream类 (3)fstream 类 10.2.3 输入/输出流类的继承层次结构 (1)流的分类及层次关系 输入/输出流的层次关系 (2) 输入/输出流类库有关的头文件 (1) iostream.h:包含对输入输出流进行操作的基本信 息,提供无格式支持的低级输入输出和有格式支持的 高级输入输出功能。 (2) ifs

7、tream.h、ofstream.h、fstream.h:包含管理文件 输入输出操作的有关信息。 v 当一个程序中需要进行标准流输入输出操作时,当一个程序中需要进行标准流输入输出操作时, 程序中必须有:程序中必须有:#include v 当一个程序中需要进行文件输入输出操作时,程当一个程序中需要进行文件输入输出操作时,程 序中必须有:序中必须有:#include /读文件读文件 #include /写文件写文件 #include /读写文件读写文件 10.2.4 流操作运算符 格式: 流对象变量变量.; “”本来在C+中被定义为左位移运算符和右位移运算符, 由于在文件iostream.h中对它

8、们进行了重载,使得它们能用作标准类 型数据的输入输出运算符。 从流中获取数据的操作称为提取操作,使用提取运算 符“”。 “”会自动忽略所有的空白字符,因此无法输入包含空格符的字符串会自动忽略所有的空白字符,因此无法输入包含空格符的字符串。如: char name20; cinname; 假如输入姓名“Tom Hanks”时,变量name中只有“Tom” 向流中添加数据的操作称为插入操作,使用插入运算符 “”。 格式: 流对象数据项数据项.; 数据项可以是常量、变量、表达式、字符串。 如:流对象a=atb=bendl; (1)字符输入成员函数 成员函数get()可以从输入流中获取字符,并将它存放

9、 在指定的变量中。该函数有以下两种格式: v ch=流对象.get() v 流对象.get(ch) 函数实现从输入流中读取一个字符,赋给字符变量ch。 采用第2种格式时,如果读取数据成功则函数返回非如果读取数据成功则函数返回非0 0值值 (真),否则(遇结束标志符)返回(真),否则(遇结束标志符)返回0 0值(假)。值(假)。 10.2.5 流读写操作成员函数 1数据输入成员函数 (2)字符串输入成员函数 从输入流中一次读取一串字符,有以下2种方 式: v流对象.get(字符数组或字符指针,字符个数n,终止 字符) v流对象.getline(字符数组或字符指针,字符个数n,终 止字符) 从输入

10、流中读取从输入流中读取n n1 1个字符个字符并并自动补以自动补以00字符串结束字符串结束 标志标志(共计(共计n n个字符个字符 ) ),赋给指定的字符数组(或字符指针指,赋给指定的字符数组(或字符指针指 向的数组)。如果在读取向的数组)。如果在读取n n1 1个字符之前遇到指定的终止字符,个字符之前遇到指定的终止字符, 则提前结束读取。如果读取成功则函数返回非则提前结束读取。如果读取成功则函数返回非0 0值(真),否值(真),否 则(遇文件结束符)返回则(遇文件结束符)返回0 0值(假)。值(假)。第三个参数缺省为换行第三个参数缺省为换行 符符。 (1)字符输出成员函数 函数put()用于

11、输出单个字符。 格式: 流对象.put(char c); put函数的参数c可以是字符或字符的ASCII码。 例如: cout.put(a); /在屏幕上显示字符a (2)字符串输出成员函数 函数write()用于输出一个指定长度的字符串。 格式:流对象.write(字符串,字符个数n) ; 例如: cout.write(This is a book. n,20); 2数据输出成员函数 【例10-1】 读取字符 输入字符:a b c c1=a c2= c3=b #include using namespace std; void main( ) char c1,c2,c3; cout输入字符:

12、; c1=cin.get(); cin.get(c2); cin.get(c3); coutc1=c1endl; coutc2=c2endl; coutc3=c3endl; 【例10-2】 读取字符串 #include using namespace std; void main() char str20; cout输入一行字符串: ; cin.getline(str,20); /也可用 cin.get(str,20); coutstr=strendl; 程序运行结果如下: 输入1行字符串: Hello,everyone. str= Hello,everyone. 10.2.6 流写操作格式控

13、制成员函数 数据输出的格式控制可通过两种途径实现: 使用流写操作()、带参数预定义格式 控制符 头文件:iomanip.h 使用由ios类定义的格式控制成员函数 头文件:iostream.h 1. 使用流操作符使用流操作符对输出操作进行格式化对输出操作进行格式化 o不带参数的流操纵符 nendl ndec/oct/hex 十/八/十六进制 o带参数的流操纵符 (注意:需包含头文件iomanip) nsetbase(int base)设置数制转换基数为base nsetfill(int ch)将填充字符设置为ch nsetprecision(int p)设置数字精度 nsetw(int w)将域

14、宽设置为w nsetiosflags(fmtflags flags)开启flags中指定的标志 nresetiosflags(fmtflags flags)关闭flags中指定的标志 其中,流格式状态标志字(flags): oios:left在域中左对齐输出,右边显示填充字符 oios:dec指定整数应作为十进制(基数10)值 oios:hex指定整数应作为十六进制(基数16)值 oios:showpos指定正数和负数前面分别加上+和-号 oios:fixed指定浮点数以小数方式输出 oios:scientific指定浮点数输出采用科学记数法 例10-3:设置实型数的精度 #include #

15、include #include using namespace std; int main() double r = sqrt( 2.0 ); int i; cout r = r endl; / 设置输出为定点小数方式 cout setiosflags( ios:fixed) ; cout 以定点小数方式: endl; for ( i = 0; i = 4; i+ ) cout setprecision( i ) r = r endl; / 取消定点小数输出方式并设置为科学记数方式 cout resetiosflags( ios:fixed) setiosflags( ios:scienti

16、fic) ; cout 以科学记数方式,采用不同精度输出: endl; for ( i = 0; i = 4; i+ ) cout setprecision( i ) r = r endl; return 0; 例例10-4:改变整数的进制:改变整数的进制 #include using namespace std; int main() int n = 30; cout 整数: n endl; cout 以十六进制显示为: hex n endl; cout 以十进制显示为: dec n endl; cout 以八进制显示为: oct n endl; return 0; 例10-5:设置输出宽度

17、、填充字符和对齐方式 #include #include using namespace std; int main() double pi=3.14159; / 以默认方式输出 cout pi endl; / 设置输出宽度后进行输出 cout setw(10) pi endl; / 使用填充字符并设置输出宽度后进行输出 cout setfill(*) setw(10) pi endl; / 设置左对齐方式及输出宽度后进行输出 cout setiosflags(ios:left) setw(10) pi endl; / 取消左对齐方式 cout resetiosflags(ios:left);

18、 / 设置右对齐方式及输出宽度后进行输出 cout setiosflags(ios:right) setw(12) pi endl; return 0; 2. 使用使用ios类的格式控制成员函数对输出操作进行格式化类的格式控制成员函数对输出操作进行格式化 o格式化函数 nwidth(w)设置显示字段宽度为w nprecision(p) 设置浮点数精度为p nfill(ch)设置填充字符为ch nsetf(flags) 设置输出格式状态为flags 其中,流格式状态标志字(flags): oios:left在域中左对齐输出,右边显示填充字符 oios:dec指定整数应作为十进制(基数10)值 o

19、ios:hex指定整数应作为十六进制(基数16)值 oios:showpos指定正数和负数前面分别加上+和-号 oios:fixed 指定浮点数以小数方式输出 oios:scientific指定浮点数输出采用科学记数法 nunsetf(flags)清除格式标记flags o其中,流格式状态标志字(flags)同前。 #include using namespace std; int main() cout.precision(4); cout.width(10); cout 10.12345 endl; cout.fill(*); cout.width(10); cout 10.12345 e

20、ndl; cout.width(10); cout Hi! endl; cout.width(10); cout.setf(ios:left); cout 10.12345endl; cout.setf(ios:uppercase | ios:scientific); cout 10.12345endl; cout.unsetf(ios:uppercase); cout 10.12345endl; return 0; 运行结果:运行结果: 10.12 *10.12 *Hi! 10.12* 1.0123E+001 1.0123e+001 例10.6 将商品名称与单价通过初始化赋给数组 mname

21、、 price,输出各商品的名称和单价,指 定商品名称域宽为10个字符、左对齐,单价为右 对齐、用定点方式、小数点后有2位有效数字。 分析: 浮点数默认的输出精度为6(即输出6位有效数 字),例如浮点数3456.7891 显示为3456.79。若 要实现指定小数点后显示几位有效数字,应先用 setf设置定点方式,再用成员函数precision(n) 设置小数点后n位有效数字。 #include using namespace std; void main() char *mname=pencil,pen,book,pencilbox,bag; double price=1.9,17.2, 8.

22、63, 24,65; for (int i=0;i5;i+) cout.setf(ios:left); /设置左对齐 cout.width(10);/设置域宽为10 coutmnamei; cout.unsetf(ios:left); cout.setf(ios:fixed); /设置定点方式 cout.precision(2); /设置小数点后2位有效数字 coutpricei变量 /读操作 输出文件流对象变量 /写操作 文件流对象成员函数实现读取 提醒:读文件时需要测试是否到达文件结束位置。 VC6.0提供的成员函数eof()只能用于单个字符的读取。 如果要从文本文件中读取通过空格或回车符

23、分隔的多 个数据项(字符串数据项或数值项)需要自己编程实 现。 关闭文件关闭文件是指撤销文件信息区和文件缓冲区,使文是指撤销文件信息区和文件缓冲区,使文 件指针变量不再指向该文件,文件关闭后无法对此件指针变量不再指向该文件,文件关闭后无法对此 文件进行读写,文件进行读写,对文件对文件起到保护作用。起到保护作用。 (4)关闭文件 文件流对象.close( ); #include #include #include using namespace std; struct student char name20;float score2; ; int main() student st3=李四,90

24、,80,王五,60,80,高大军,50,90; char fname=text.txt; /-写文件- ofstream outfile(fname); /定义文件输入流对象,打开源文件 if (!outfile) cout不能打开源文件:fnameendl; return 0; for(int i=0;i3;i+) outfilesetw(10)setw(10)sti.score0 setw(10)sti.score1endl; outfile.close(); /关闭目标文件 10.3.2 文本文件的写()/读get() /-读文件- ifstream infile(fna

25、me); /定义文件输出流对象,打开目标文件 if (!infile) cout不能打开源文件:fnameendl; return 0; char ch; while(!infile.eof() ch=infile.get(); /从源文件中提取一个字符到变量ch中; coutch; infile.close(); /关闭源文件 return 1; 补充实例1数据写入文本文件 某班有N个学生,包含学号、姓名、语文成绩、数学 成绩、英语成绩,从键盘输入数据,将这些信息写入 文件date.txt。 #include #include #include using namespace std; #d

26、efine N 4 struct student char xh10,name10; int yw,sx,yy; ; void main() student stN=.; /将数据写入文件 fstream file; file.open(date.txt,ios:out); for(int i=0;iN;i+) filesetw(12)sti.xhsetw(12); filesetw(12)sti.ywsetw(12)sti.sx setw(12) sti.yy 设有数据文件date.txt,存放了N个学生的记录。每个 记录包括学号、姓名、语文成绩、数学成绩、英语成 绩,数据项

27、用空白字符分隔。 从文件读取数据,求每个学生的平均成绩,并按 每个记录包括学号、姓名、平均成绩(保留两位小数) 的方式在屏幕上对齐显示出来。 #include #include #include using namespace std; #define N 4 struct student char xh10,name10; int yw,sx,yy; float ave; ; void main() fstream file;fstream file; student stN; /从文件中读取数据 file.open(date.txt,ios:in); for(i=0;isti.xhsti.

28、namesti.ywsti.sx sti.yy; sti.ave=(sti.yw+sti.sx+sti.yy)/3.0; coutsetw(12)sti.xhsetw(12) setiosflags(ios:fixed)setprecision(2) setw(12)sti.aveendl; file.close(); 思考与挑战: 如果不知道文件记录数怎么办? 完 其它内容自学 实验7:输入输出流程序设计 o 题目(作业):将补充实例按平均平均成绩排 序后写入sort.txt o 要求: (1)实验前编号程序,上机调试、改进、运行。 (2)只提交.CPP程序,共提交2个源程序

29、,其它 文件不得提交 (3)为便于作业管理,文件命名规定如下: .CPP 班次学号题号 07120103.cpp 7班12号第1章03 题 章次 2使用成员函数进行文件的读写操作 例10.7 使用成员函数get与put将源文件的内容复制到 目标文件中 分析:先打开源文件和目标文件,依次从源文件中读取一 个字符,并将所读字符写入目标文件中,直到源文件中所 有字符读完为止。 #include #include using namespace std; void main( ) char fname120,fname220; coutfname1; ifstream infile; / 定义文件输入

30、流对象 infile.open(fname1, ios:in );/打开源文件 if (!infile) cout源文件不存在!fname1endl; return; coutfname2; ofstream outfile; / 定义文件输出流对象 outfile.open(fname2,ios:out );/打开目标文件 char ch; while (infile.get(ch) /从源文件中提取一个字符到变量ch; outfile.put(ch); /将ch中的字符写入目标文件中。 infile.close(); outfile.close(); 说明说明: (1)用成员函数)用成员函

31、数get获取字符时,不跳过其中的空白字获取字符时,不跳过其中的空白字 符,因此可以复制源文件中的所有字符;符,因此可以复制源文件中的所有字符; (2)while(infile.get(ch)用于判断读入的字符是否为文用于判断读入的字符是否为文 件结束标识件结束标识”0” 10.3.3 二进制文件的读写(自学) 1二进制文件的读操作 二进制文件的读操作是通过成员函数read() 来实现: read(read(字符数组或字符指针字符数组或字符指针, , 字节数字节数 ); ); 2. 二进制文件的写操作 二进制文件的写操作是通过成员函数write() 来实现: write(write(字符数组或字

32、符指针字符数组或字符指针, , 字节数字节数); ); 3测试文件结束 测试二进制文件结束位置可用成员函数eof() 实现,当到达文件结束位置时,该函数返回零值, 否则返回非零值。 4返回读入数据的长度 返回最近一次输入所读入的字节数可用成员函数 gcount()实现。 【例10.8】 把090度的正弦值写到二进制文件bin.dat中 #include #include # include using namespace std; void main () fstream outfile(bin.dat,ios:out | ios:binary); int i; if (!outfile) c

33、out不能打开输出文件n; return; double s91; for (i=0;i=90;i+) si=sin(i*3.1415926/180); outfile.write(char * )s,sizeof(double) * 91); /一次写入91个实 数 outfile.close(); 【例10.9】 从例【10.8】的程序建立的二进制文件bin.bat中读入数据, 以每行5个数据的形式 显示在屏幕上,数据输出到小数点后15位。 /*ex10.9.cpp* #include #include #include using namespace std; void main() d

34、ouble s91; int i; fstream infile(bin.dat,ios:in|ios:binary); if(!infile) cout输入文件不存在n; return; infile.read(char*)s,sizeof(double)*91); for(i=0;i=90;i+) coutsetiosflags(ios:fixed)setprecision(15)sit; if(i+1)%5=0)coutendl; infile.close(); 【例10.10】 使用读写二进制的成员函数,实现文件的复制。 #include #include using namespac

35、e std; int main() char fname120,fname220; char buff4096; /建立4K缓冲区 fstream infile,outfile; coutfname1; infile.open(fname1,ios:in | ios:binary ); if (!infile) cout不能打开输入文件:fname1endl; return(1); coutfname2; outfile.open(fname2,ios:out| ios:binary ); if (!outfile) cout目标文件fname2已存在!endl; return(2); int

36、 n; while (!infile.eof() infile.read(buff,4096); n=infile.gcount(); /取实际读的字节数 outfile.write(buff,n); /按实际读的字节数写入文件 infile.close(); outfile.close(); return(0); 10.3.4 文件的随机读写 从文件中任何位置开始进行读或写数据,这种读写方式称 为文件的随机访问或直接存取。 1文件定位 C+ 的类库fstream中定义了两个与文件相联系的指针 v 读指针 v 写指针 C+的文件定位分为读位置和写位置的定位,对应的成 员函数 v seekg()

37、:设置读位置 v Seekp:设置写位置 1 seekg函数 seekg(位移量n); seekg(位移量n, 参照位置 ); 第1种格式专用于相对文件头指针移动n个字节,第2种格 式用于相对参照位置指针移动n个字节。参照位置可取 三个值: io3:beg或0:文件头。 io3:cur或1:文件指针当前的位置。 io3:end或2:文件尾。 2 seekp函数 文件写操作的定位是通过成员函数seekp实现的。 函数的格式如下: seekp(位移量n); seekp(位移量n, 参照位置 ); 第1种格式专用于相对文件头指针移动n个字节, 第2种格式用于相对参照位置指针移动n个字节。 3. tellg函数 返回输入文件中文件指针的当前位置是通过成员函数 tellg实现的,该函数的返回值为streampos类型。 利用seekg和tellg可以获取文件的大小。例如: ifstream tfile(fname, ios:in | ios:nocreate); tfile.seekg(0,ios:end); long n=tfile.tellg(); cou

温馨提示

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

评论

0/150

提交评论