




已阅读5页,还剩76页未读, 继续免费阅读
版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
第11章输入输出流类库,本章导读,在C+语言中并没有输入/输出语句,其目的是为了最大限度地保证语言与平台的无关性。为了实现输入/输出操作,C+提供了两种方法:一是通过C+提供的与C语言兼容的输入/输出库函数;二是提供了功能强大的输入/输出流类库,在C+中应提倡使用输入/输出流类库来实现。数据从一个对象到另一个对象的传送被抽象为“流”。C+中,外部向内存提供数据的过程称输入流,数据提供者可以是输入设备,也可以是提供数据的文件。同样从内存向外发送数据的过程称输出流,数据接收者可以是输出设备,也可以是保存所接收数据的文件。,计算机的输入/输出主要操作对象是外部设备或数据文件。计算机的外部设备很多,其中键盘和显示器是最重要的输入/输出设备,C+中将键盘作为标准输入设备,显示器作为标准输出设备。在C+中,输入/输出是通过类来描述的,称作流类,提供流类实现的系统称输入/输出流类库。,本章提要:,1.流概述2.C+的基本流类体系3.标准输入/输出4.文件输入/输出5.文本文件的使用6.二进制文件的使用,11.2流概述,流是一个抽象的概念,数据从一个设备(或存储位置)到另一个对象(或存储位置)的传送通道抽象为“流”。1.流和标准流流是通过称作流类所定义的对象,而流类是用于完成输入/输出操作的类,该类由C+标准库函数iostream.h提供,如cin、cout等。,计算机硬件的五大部件中,输入/输出设备种类繁多,但键盘和显示器是最常用的输入/输出设备,C+中,把键盘和显示器定义为标准设备。在C+中,针对标准设备实现的输入/输出操作,称标准流。标准流有四个:cin、cout、cerr和clog。其中cin是标准输入流,实现从键盘输入数据;其他三个是标准输出流,实现从显示器输出数据(cerr和clog为标准错误信息输出流)。,2.流和缓冲在实现输入/输出时,计算机系统专门为输入/输出设备开辟一个临时存放信息的区域称缓冲区。引入缓冲的主要目的是为了提高系统的处理效率。在四个标准流中,除cerr为非缓冲流外,其他三个均为缓冲流。对于非缓冲流,一旦数据送入流中,立即进行处理。而对于缓冲流,只有当缓冲区满时,或当前送入换行字符时,系统才对流中的数据进行处理。通常情况下使用缓冲流,对于某些特殊场合,才使用非缓冲流。如果需要立即处理缓冲区中的信息,应强制刷新输出流,此时可在cout的输出项中使用刷新流flush。,3.流和文件文件是由文件名作为标识的一组有序数据的集合,文件通常存放在磁盘上,所以一般又称磁盘文件。C+提供了两种类型的流:文本流(TextStream)和二进制流(BinaryStream)。对应的数据文件也分为两种:文本文件和二进制文件。(1)文本文件:由字符的ASCII码组成,以字符为单位存取。文本文件也称为ASCII码文件。(2)二进制文件:由二进制数据组成,以字节为单位存取。二进制文件在传送时均采用二进制流。二进制流与设备上的输入输出一一对应,在数据传送时不需作任何变换。,11.3C+的基本流类体系,C+的输入/输出流类库包含在iostream.h头文件中。程序中需要完成基本输入/输出操作时,应包含iostream.h头文件,其流类体系见图。,1基类ios类ios是所有基本流类的基类,其它基本流类均由该类派生而来。2输入流类istream输入流类istream派生出istream_withassign类,输入流cin就是由istream_withassign定义的对象。3输出流类ostream输出流类ostream派生出ostream_withassign类,输出流cout就是由ostream_withassign定义的对象。4输入输出流类iostreamiostream流类是类istream和ostream共同派生的。,11.4标准输入/输出流,基本流类库定义了四个标准流:cin、cout、cerr、clog,以实现数据流的输入与输出操作。11.4.1标准输入流在C+流类体系中定义的标准输入流是cin,cin是由输入类istream的派生类istream_withassign定义的对象,cin所对应的是标准输入设备键盘,标准输入流cin通过重载“”运算符实现数据的输入操作,当执行输入操作时,cin可看作从标准输入流中提取与操作数相匹配的字符序列。cin为缓冲流。标准输入流实现提取操作时,系统将自动完成数据类型的转换。,例【11.1】使用流cin实现数据的输入。#includevoidmain(void)inta;couti;cout”i=”iendl;,11.4.2标准输出流,在C+流类体系中定义的标准输出流是cout、cerr、clog,它们是由输出类ostream的派生类ostream_withassign定义的对象,在缺省的情况下,cout、cerr、clog所联系的设备文件为显示器,即将数据流输出到显示器上。标准输出流cout、cerr、clog通过重载“”运算符执行数据的输出操作,执行输出操作看作向流中插入一个字符序列,因此将“r;clog”r=”3.14159*r*r”运算符来实现的。在C+中,允许用户根据需要自定义istream的对象,以实现通过其他设备输入数据。当程序中包含头文件iostream.h,系统将自动产生输入流cin。【例11.3】通过输入流cin分别输入十进制、八进制、十六进制数。,#includevoidmain()inta,b,c;coutdeca;coutoctb;couthexc;couta=aendl;coutb=bendl;coutc=cendl;,3.输出流格式控制,输出流cout与插入运算符“”输出数据时,可对输出数据的格式进行控制,包括输出宽度、输出位置(实现对齐)、精度、填充方式、进制格式等。(1)不同进制数输出C+中也有两种设置方式实现不同进制数的输出:使用setiosflags函数和使用C+预定义的格式控制符dec、oct、hex。【例11.4】用setiosflags函数与格式控制符dec、oct、hex,分别实现十进制、八进制和十六进制数的输出。,#include#includevoidmain()inti=100;coutdecitocti;coutthexiendl;coutdec;coutsetiosflags(ios:dec)it;coutsetiosflags(ios:oct)it;coutresetiosflags(ios:oct);coutsetiosflags(ios:hex)it;coutresetiosflags(ios:hex)iendl;,预定义格式控制函数setiosflags的一般格式为:setiosflags()其中:所表示的主要枚举量值如下:ios:dec指定输入/输出格式为十进制数(默认)ios:oct指定输入/输出格式为八进制数ios:hex指定输入/输出格式为十六进制数ios:skipws在输入中跳过空白ios:left左对齐,右边用指定填充字符填充ios:right右对齐,左边用指定填充字符填充(默认方式)ios:internal在符号或数制字符后进行填充ios:showpoint对浮点数显示小数点及尾部的0ios:showpos正数时显示正号符号(+)ios:scientific用科学记数法输出浮点数ios:fixed用小数点固定格式输出浮点数,(2)设置输出宽度及填充字符设置输出宽度有两种方法:通过由ios类中定义的输出格式控制成员函数width(intn)和预定义格式控制函数setw(intn)实现。这两个函数的int类型参数n是表示需输出数据的宽度。设置输出宽度时,还可以结合填充成员函数fill(charc)填充字符,其中字符c是需要填充的字符。width成员函数与fill成员函数均在头文件iostream.h中说明。而预定义格式控制函数setw在头文件iomanip.h中说明。,【例11.5】分别使用width成员函数和预定义格式控制函数setw控制输出宽度,同时通过函数fill填充字符。#include#includevoidmain()floatpi=3.14125;cout.width(10);coutpiendl;cout.width(10);cout.fill(#);coutpiendl;cout.fill();coutsetw(10)piendl;coutsetw(10);cout.fill(*);coutpiendl;,(3)控制数值输出精度浮点数输出时,其默认输出的精度为6位。当需要改变输出精度时,可通过预定义格式控制函数setprecision(intn)来设置,其中整型类型n,使用setiosflags(ios:fixed)设置定点输出方式时,是小数点后的有效位数。使用setiosflags(ios:scientific)设置科学记数输出方式时,是整个数值的位数(总长度)。,【例11.6】通过格式控制输出数值的有效位数。#include#includevoidmain()doublepi=314.12596;coutpiendl;/Acoutsetiosflags(ios:fixed)setprecision(6);coutpiendlresetiosflags(ios:fixed);/Bcoutsetiosflags(ios:scientific)setprecision(10);coutpiendlresetiosflags(ios:scientific);/C,(4)缓冲区与刷新流通过缓冲流实现输出时,只有当缓冲区满时,才对输出流中的数据进行处理。如果需要立即处理缓冲区中的信息,可通过强制刷新输出流,实现即时输出。在cout的输出项中可使用刷新流flush。,例【11.7】使用缓冲流cout和非缓冲流cerr实现输出情况的比较。#includevoidmain()inta=10;cerr通过cerr输出!n;/Acout通过cout输出!n;/Bcouta/0”和插入运算符“”实现输入/输出操作外,C+还提供一些相应的成员函数,实现数据的输入/输出操作。1.输入操作的成员函数(1)单个字符输入的成员函数输入单个字符的成员函数有两种格式:intistream:get();istream,例【11.8】分别使用两种格式输入字符。#includevoidmain()charc1,c2;c1=cin.get();cin.get(c2);coutc1tc2endl;,(2)字符串输入的成员函数字符串输入的成员函数也有两种格式:istream,例【11.9】分别使用两种格式输入字符串。#includevoidmain()charc1100,c2100;cin.get(c1,100);/Acin.getline(c2,100,u);/Bcoutc1c2”运算符重载,不可以通过成员函数实现。其原因是这两个运算符的左操作数不可能是该类的对象,而是流类的对象cin、cout等。(1)重载提取运算符“”的一般格式为:friendistream,重载提取运算符“”时,函数返回值必须是类istream的引用。非引用时,cin后面只能有一个提取运算符,如果要满足cin中可以连续使用“”运算符,则必须是引用。格式中,运算符重载函数的第一个参数也必须是类istream的引用,作为运算符的左操作数,第二个参数为自定义类的对象引用,作为运算符的右操作数。须注意,在重载提取运算符“”时,第二个参数必须是引用,否则在运算符重载函数中对对象的输入,无法返回到对应的实参对象。,(2)重载插入运算符“”类同,重载插入运算符“”时,函数返回值必须是类ostream的引用,这也是为了在cout中可以连续使用“”运算符。函数的第一个参数是类ostream的引用,第二个参数为自定义类的对象或对象引用。,【例11.12】重载提取和插入运算符,实现时间类的输入和输出。#includeclassTimeintHour,Minute,Second;public:Time(inth=0.0,intm=0.0,ints=0)Hour=h;Minute=m;Second=s;friendostream,ostream/B,11.5.1文件概述文件是由文件名标识的一组有序数据的集合,文件通常存放在磁盘上。在C+中,磁盘文件只是文件的一种,具体的外部设备,也可以抽象为文件,系统为每个外部设备都指定唯一的一个设备名(文件名)。这样对外部设备的操作也抽象为对文件的操作,对程序设计而言,只要掌握文件的操作,就可以实现对不同具体设备的操作,实现了语言与设备的无关。,11.5文件流,在C+中,文件分为两种:文本文件和二进制文件。(1)文本文件:由字符的ASCII码组成,以字符为单位存取。文本文件也称为ASCII码文件。(2)二进制文件:由二进制数据组成,以字节为单位存取。使用文件时,必须先打开文件,然后才能对文件进行读或写操作,操作完成后应关闭文件。,在C+头文件fstream.h中,定义了文件流类体系,文件流类体系如图。由图可知C+的文件流类体系是从C+的基本流类体系中派生出来的。当程序中使用文件时,需要包含头文件fstream.h。,11.5.2文件流类体系,11.5.3文件的使用方法,在C+中,文件的使用主要有打开、读/写、关闭文件等操作。使用文件首先需要通过文件输入流类ifstream、文件输出流类ofstream或文件输入/输出流类fstream定义文件流对象(也直接称文件流),然后通过文件流调用对应的成员函数完成对文件的相关操作。,对文件的操作一般有三种情况:从文件读数据、向文件写数据、对文件既可读也可写操作。所有文件流都通过流类ifstream、ofstream、fstream定义。其中,ifstream只能用来定义读文件流对象,如:ifstreaminfile;ofstream只能用来定义写文件流对象,如:ofstreamoutfile;fstream用来定义既可读也可写的文件流对象,如:fstreamiofile。,1.打开文件使用一个文件时必须先将其打开,其目的是将一个文件流与一个具体的磁盘文件联系起来,然后通过相关的文件流提供的成员函数,实现数据的写入或读取。打开文件有二种方式:文件流通过open成员函数或在定义文件流对象时通过构造函数。(1)使用成员函数open打开文件三种文件流对应的open函数格式如下:voidifstream:open(constchar*,int=ios:in,int=filebuf:openprot);voidofstream:open(constchar*,int=ios:out,int=filebuf:openprot);voidfstream:open(constchar*,int,int=filebuf:openprot);,文件打开方式有以下八种:ios:in/按读(输入)方式打开文件,若文件不存在,则自动建立新文件ios:out/按写(输出)方式打开文件,若文件不存在,则自动建立新文件ios:ate/打开文件,使文件读写指针移到文件末尾ios:app/打开文件,不删除文件数据,将新数据增加到文件尾部ios:trunc/打开文件,并清除文件原有数据(默认方式)ios:nocreate/只能打开已存在文件,如文件不存在则打开失败。通常nocreate方式不单独使用,总是与读/写方式同时使用。,ios:noreplace/建立新文件,如文件已存在则建立失败ios:binay/必须明确指定binary方式打开文件,才是二进制文件,该标志总是与读或写同时使用,表示打开二进制文件。在使用上述打开方式时,可以把多种方式结合在一起使用,中间用|连接。如:ios:out|ios:app,表示按写(输出)方式打开文件,并把新写的数据添加到文件末尾。,提示:表示路径名的“”要用连续两个表示,第一个表示转义序列开始。如有文件e:testdata.txt,其路径名和文件名应表示为:e:testdata.txt。i通过open函数打开文件的语句为:ifstreaminfile;infile.open(e:testdata.txt);ofstreamoutfile;outfile.open(e:testdata.txt);fstreamiofile;iofile.open(e:testdata.txt,ios:in|ios:out);,(2)定义文件流对象时,通过构造函数打开文件在文件流类中,都带有缺省参数的构造函数,可以在定义文件流对象时,通过构造函数打开文件,格式为:ifstream:ifstream(constchar*,int=ios:in,int=filebuf:openprot);ofstream:ofstream(constchar*,int=ios:out,int=filebuf:openprot);fstream:fstream(constchar*,int,int=filebuf:openprot);,在定义文件流同时通过构造函数打开文件的语句为:ifstreaminfile(e:testdata.txt);ofstreamoutfile(e:testdata.txt);fstreamiofile(e:testdata.txt,ios:in|ios:out);提示:打开文件时,一般要判断打开是否成功。若文件打开成功,则文件流对象值将为非零值,若打开不成功,则文件流对象值为0。测试打开文件是否成功的程序段如下:ifstreaminfile(e:testdata.txt);if(!infile)coutch;从输入文件流infile所关联的文件e:testdata.txt中提取一个字符赋于变量ch。outfilech;将变量ch中字符插入到输出文件流outfile所关联的文件e:testdata.txt中去。,另一种方法是使用成员函数对文件进行读写操作。例如:charch;infile.get(ch);从输入文件流infile所关联的文件e:testdata.txt中读取一个字符赋于变量ch。outfile.put(ch);将变量ch中字符写入到输出文件流outfile所关联的文件e:testdata.txt中去。,3.关闭文件当文件读/写操作完成后,应该立即关闭所打开的文件。关闭文件由close成员函数完成。关闭文件的成员函数是:voidifstream:close();voidofstream:close();voidfstream:close();关闭文件时,系统将该文件内存缓冲区中的数据写到文件中,断开文件流对象和该文件名之间所建立的关联。使用时,通过文件流对象调用,如infile.close()。提示:关闭文件只是断开文件流对象与实际文件之间所建立的关联,其文件流本身并没有撤消,文件流对象还可以通过open函数与其他文件建立关联。,【例11.13】把1100的所有数据存放到文件data1.dat文件中。#includevoidmain(void)fstreamoutfile(data1.dat,ios:out);/ofstreamoutfile(data1.dat);/fstreamoutfile;/outfile.open(data1.dat,ios:out);for(inti=1;i=100;i+)outfileia;/Acouta”和插入运算符“ch)outfilech;infile.close();outfile.close();,【例11.16】使用get()函数和put()函数将例11.13中建立的data1.dat数据文件复制到data3.dat。#include#include#includevoidmain(void)ifstreaminfile(data1.dat,ios:in|ios:nocreate);/通过输入流类定义输入流infile,打开方式为输入并且文件已经/在指定位置存在,否则无法打开。ofstreamoutfile(data3.dat);,if(!infile)/打开文件时,如指定文件不存在,则表达式!infile为真值。cout不能打开data1.dat数据文件!n;exit(1);infile.unsetf(ios:skipws);charch;while(infile.get(ch)/Aoutfile.put(ch);/Binfile.close();outfile.close();,【例11.17】说明一个结构体类型,建立学生档案。#includestructstudentcharname10;charsex4;intage;floatcscore;,voidmain(void)students3=张敏,男,20,83,王平,男,21,78,刘丽,女,20,90;ofstreamoutfile(student.txt);/通过输出流类定义输出流outfile,/并通过构造函数与文件student.txt建立关联。for(inti=0;i3;i+)si.sexsi.agesi.cscoresi.sexsi.agesi.cscore;/通过提取运算符把数据文件中的数据读到数组各元素中。for(i=0;i3;i+)cout姓名:t性别:si.sext;cout年龄:si.agetc+课程成绩:si.cscoren;/通过标准输出流把数组各元素输出到屏幕。infile.close();,【例11.19】分别通过插入运算符、get()函数、getline()函数put()函数实现对文字信息文本文件的输入/输出。#includevoidmain(void)charstr1100=Iamastudent!;charstr2100=Youareastudent!;charstr3100=Heisastudent!;charch;ofstreamoutfile(data4.txt);outfilestr1n;outfilestr2n;outfilestr3n;/通过插入运算符把字符串写入到文本文件,outfile.close();ifstreaminfile(data4.txt,ios:in|ios:nocreate);outfile.open(data4a.txt);while(infile.get(ch)outfile.put(ch);infile.close();outfile.close();infile.open(data4a.txt,ios:in|ios:nocreate);while(infile.getline(str1,100)coutstr1endl;infile.close();,11.7二进制文件的使用,在C+中,文件分为两种类型:文本文件和二进制文件。文件的类型不同,文件中数据的存放格式就不同,因此在对文件进行读写操作时,必须区分文本文件和二进制文件。在C+流类的基类中,提供了ios:binary打开方式标志。打开文件时,如果没有ios:binary标志,则表示是文本文件,反之是二进制文件。,11.7.1二进制文件的打开和关闭,打开二进制文件时,不论是通过open成员函数还是通过构造函数与文件建立联系,都须包含ios:binay标志。如通过open函数打开二进制文件的语句:ifstreaminfile;infile.open(e:testdata.txt,ios:in|ios:binary);ofstreamoutfile;outfile.open(e:testdata.txt,ios:out|ios:binary);fstreamiof;iof.open(e:testdata.txt,ios:in|ios:out|ios:binary);,通过构造函数打开二进制文件的语句:ifstreaminfile(e:testdata.txt,ios:in|ios:binary);ofstreamoutfile(e:testdata.txt,ios:out|ios:binary);fstreamiof(e:testdata.txt,ios:in|ios:binary);强调打开二进制文件,必须在第二参数中包含ios:binary标志。二进制文件的关闭方式与文本文件完全相同。,11.7.2二进制文件的读/写,1.read()函数对二进制文件的读操作通过read()成员函数实现。read()函数的格式如下:istream函数中第二个整型参数表示要读出数据的大小(单位是字节),第一个参数是字符型指针表示要读入的数据所存放的存储单元。,2.write()函数对二进制文件的写操作是通过write()成员函数实现。write()函数的格式如下:ostream函数中第二个整型参数表示要写入数据的大小(单位是字节),第一个参数也是字符型指针表示要准备写入数据所存放的位置。提示:在read()函数和write()函数中,第一个参数必须是字符指针,如果是其他类型则必须强制转换成字符指针类型。,3.eof()函数当读取二进制数据文件时,可通过eof()成员函数判断是否到文件结束位置。eof()成员函数的格式为:intios:eof();当读取数据到达文件结束位置时,eof()函数返回非零值,否则返回零值。eof()函数常用于读取数据时,判定数据是否读取完毕。,【例11.20】把1100的所有数据存放到二进制文件data5.dat中。#includevoidmain(void)ofstreamoutfile(data5.dat,ios:out|ios:binary);for(inti=1;i=100;i+)outfile.write(char*),【例11.21】把上例建立的二进制文件data5.dat中所有数据读出并显示在屏幕上。#include#includevoidmain(void)ifstreaminfile(data5.dat,ios:in|ios:binary);inta;while(!infile.eof()infile.read(char*),【例11.22】把例11.19建立的二进制文件data5.dat中所有数据,一次读出并显示在屏幕上。#include#includevoidmain(void)ifstreaminfile(data5.dat,ios:in|ios:binary);inta100;infile.read(char*)a,sizeof(int)*100);for(inti=0;i100;i+)coutait
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
评论
0/150
提交评论