输入输出流与流类库_第1页
输入输出流与流类库_第2页
输入输出流与流类库_第3页
输入输出流与流类库_第4页
输入输出流与流类库_第5页
已阅读5页,还剩94页未读 继续免费阅读

下载本文档

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

文档简介

第二章输入输出流与流类库,09:10:12,2/99,流的定义、C+的预定义流标准输入输出的预定义流对象cin、cout、cerr和clog格式化的I/O输入流/输出流专门操作文件与文件流文件操作:打开和关闭、文件的定位与随机存取、文件的读写,09:10:12,3/99,I/O流的概念,当程序与外界环境进行信息交换时,存在着两种对象,一种是程序中的对象,另一种是文件对象。流是一种抽象,它负责在数据的生产者和数据的消费者之间建立联系,并管理数据的流动。把数据的流动称为流。流在使用前要被建立,使用后要被删除,还要使用一些特定的操作,从流中获取数据或向流中添加数据。读操作在流数据抽象中被称为(从流中)提取,即输出,写操作被称为(向流中)插入,即输入。程序建立一个流对象,并指定这个流对象与某个文件对象建立连接,程序操作流对象,流对象通过文件系统对所连接的文件对象产生作用。,09:10:12,4/99,iostream类库概述,输入/输出操作在C和C+中没有定义,所有的C+编译器绑定了iostream类,用于I/O操作。在iostream类中,“流(stream)”是其核心概念。我们可以认为流对象就象一个“杰出的文件”,是字节数据出入的源和目的地。,09:10:12,5/99,iostream类库中各类间的关系图,iostream类库概述,09:10:12,6/99,ios类,ios类用来提供流的高级I/O操作。它是一个虚基类。提供输入输出所需的公共操作。ios类包含一个指向streambuf的指针,提供格式化标志进行格式化I/O处理,对I/O的错误处理,设置文件模式以及提供建立相关流的方法。,iostream类库概述,09:10:12,7/99,streambuf类,streambuf类主要负责缓冲区的处理。它提供对缓冲区的低级操作,如设置缓冲区,对缓冲区指针进行操作,从缓冲区提取字节,向缓冲区插入字节等filebuf,strstreambuf和stdiobuf都是streambuf的派生类filebuf提供文件缓冲区的管理strstreambuf使用字符串保存字符序列,提供在内存中提取和插入操作的缓冲区管理stdiobuf提供标准I/O文件的缓冲区管理,iostream类库概述,09:10:12,8/99,ostream类及其派生类提供流的各种格式化、非格式化操作,对所有系统预定义的输出流重载运算符“”,它有3个派生类:ifstream文件输入流类,用于对文件的提取操作istrstream串输出流类,用于对字符串的提取操作istream_withassign为标准输入流cin定义的输入流类,重载了赋值运算符。,iostream类库概述,istream类及其派生类,09:10:12,10/99,iostream由istream和ostream派生而来,综合了流的输入输出操作。它有3个派生类:文件输入输出流类fstream串输入输出流类strstream标准输入输出流类stdiostreamios类中的很多操纵符(以一个流引用作为其参数,并返回同一流的引用,故它可以嵌入到输入/输出操作的链中)都可以应用于输入流。操作符是在头文件iostream.h中定义的,而操作函数是在iomanip.h中定义。,iostream类库概述,输入输出流类iostream,09:10:12,11/99,屏幕输出,方法1:输出流使用预定义的插入()运算符(ostream类中定义的运算符),是所有标准C+数据类型预先设计的最重要的三个输出流是ostreamofstreamostringstream,屏幕输出和键盘输入,09:10:12,12/99,屏幕输出,预先定义的输出流对象:cout标准输出cerr标准错误输出,没有缓冲,发送给它的内容立即被输出。clog类似于cerr,但是有缓冲,缓冲区满时被输出。,屏幕输出和键盘输入,09:10:12,13/99,屏幕输出,格式:ostream,屏幕输出和键盘输入,09:10:12,14/99,ostream功能:重载的操作符把对应的参数插入到输出流中,09:10:12,15/99,屏幕输出,方法2:使用成员函数put()格式:ostream,屏幕输出和键盘输入,09:10:12,16/99,功能:从一缓冲区中把指定数量的字节数插入到输出流中。例1#includeusingnamespacestd;viodmain()inta=12;couta),提取运算符()对于所有标准C+数据类型都是预先设计好的。cin标准输入。是从一个输入流对象获取字节最容易的方法。ios类中的很多操纵符都可以应用于输入流。但是只有少数几个对输入流对象具有实际影响,其中最重要的是进制操纵符dec、oct和hex。,屏幕输出和键盘输入,09:10:12,18/99,输入流成员函数,open()函数把该流与一个特定磁盘文件相关联。get()函数的功能与提取运算符()很相像,主要的不同点是get函数在读入数据时包括空白字符。getline()的功能是从输入流中读取多个字符,并且允许指定输入终止字符,读取完成后,从读取的内容中删除终止字符。read()成员函数从一个文件读字节到一个指定的内存区域,由长度参数确定要读的字节数。如果给出长度参数,当遇到文件结束或者在文本模式文件中遇到文件结束标记字符时结束读取。,屏幕输出和键盘输入,09:10:12,19/99,输入流成员函数,seekg()函数用来设置输入文件流中读取数据位置的指针tellg()函数返回当前文件读指针的位置close()函数关闭与一个输入文件流关联的磁盘文件,屏幕输出和键盘输入,09:10:12,20/99,键盘输入,方法1:输入流重要的输入流类:istream类最适合用于顺序文本模式输入;cin是其派生类istream_withassign的对象ifstream类支持磁盘文件输入istringstream,屏幕输出和键盘输入,09:10:12,21/99,键盘输入,使用提取运算符()的格式:istream,屏幕输出和键盘输入,09:10:12,22/99,istream功能:从流对象中提取数据。,09:10:12,23/99,键盘输入,方法2:使用成员函数get()格式:intget();istream,09:10:12,24/99,get()函数功能:intget()不带参数的函数get从指定的输入流中提取一个字符(包括空白字符),并返回该字符作为函数调用的值。当遇到文件结束符时,返回系统常量EOFistreamvoidmain()inta;charp11;cina;cin.get(p,10,a);coutaendl;/endl相当于ncoutpendl;cin.read(p,4);/从输入流当前位置读取4个字节,写入到p中coutpendl;,因为endl包含在std中,所以如果用了usingnamespacestd,那么就不用加头文件了。,为什么此处使用操纵符“endl”时不用包含“iomanip.h头文件?,09:10:12,27/99,输出宽度,为满足用户对数据输入输出的格式化需要,ios提供直接设置标志字的控制格式函数为了调整输出,可通过在流中放入setw操纵符或调用width成员函数为每个项指定输出宽度intwidth(intnw)设置下一个输出项的显示宽度为nw。如果nw大于数据所需宽度,在没有特别指示时,数据以右对齐方式显示。如果nw小于数据所需宽度,则nw无效,数据以默认格式输出。该函数设置没有持续性,输出一个项目后,恢复系统的默认设置,格式控制,09:10:12,28/99,例3使用width控制输出宽度#includeusingnamespacestd;intmain()doublevalues=1.23,35.36,653.7,4358.24;for(inti=0;i4;i+)cout.width(10);coutvaluesin;,Theoutputlookslikethis:1.2335.36653.74358.24,09:10:12,29/99,设置填充字符函数charfill(charcFill)当设置宽度大于数据显示需要宽度时,空白位置以字符参数cFill填充。若数据在宽度域左对齐,在数据右边填充,否则在左边填充。默认填充符为空白符。如果要在同一行上为输出的数据设置宽度可以使用setw()函数,该函数在iomanip.h文件中做了声明,在使用该函数时,必须包括该头文件。,设置填充字符和设置显示宽度,格式控制,09:10:12,30/99,例4使用*填充#includeusingnamespacestd;voidmain()doublevalues=1.23,35.36,653.7,4358.24;for(inti=0;i4;i+)cout.width(10);cout.fill(*);coutvaluesiendl;,Theoutputlookslikethis:*1.23*35.36*653.7*4358.24,09:10:12,31/99,例5使用setw指定宽度#include#includeusingnamespacestd;voidmain()doublevalues=1.23,35.36,653.7,4358.24;char*names=Zoot,Jimmy,Al,Stan;for(inti=0;i4;i+)coutsetw(6)namesisetw(10)valuesiendl;,Theoutputlookslikethis:Zoot1.23Jimmy35.36Al653.7Stan4358.24,09:10:12,32/99,输出对齐默认是右对齐文本,如果要左对齐文本,可以使用setiosflags(ios:lFlags)函数,参数传入ios类中数据成员ios:left为使前面例子中name中的字符串左对齐,value中的数值右对齐。修改循环段的内容如下:for(inti=0;i4;i+)coutsetiosflags(ios:left)setw(6)namesiresetiosflags(ios:left)/*清除原有设置*/setw(10)valuesiendl;,输出对齐,格式控制,输出结果如下:Zoot1.23Jimmy35.36Al653.7Stan4358.24,09:10:12,33/99,在ios类中声明了一个数据成员,用于记录当前流的格式化状态,这个数据成员称为标志字。标志字的每一位用于记录一种格式。为便于记忆,每一种格式定义了对应的枚举常量。上例中只是使用了ios类中标志字ios:left下表列出了常用的标志常量名及意义:,09:10:13,34/99,09:10:13,35/99,设置显示精度,系统提供显示精度的默认值是6。float类型最大设置示数精度是6位,double类型最大设置示数精度是15位。我们可以根据需要设置示数精度修改上例中循环部分内容如下:for(inti=0;i4;i+)coutsetiosflags(ios:left)setw(6)namesiresetiosflags(ios:left)/*清除原有设置*/setw(10)setprecision(1)valuesiendl;,格式控制,输出结果如下:Zoot1Jimmy4e+001Al7e+002Stan4e+003,09:10:13,36/99,例6控制输出精度#include#includeusingnamespacestd;intmain()doublevalues=1.23,35.36,653.7,4358.24;char*names=Zoot,Jimmy,Al,Stan;coutsetiosflags(ios:scientific);for(inti=0;i4;i+)coutsetiosflags(ios:left)setw(6)namesiresetiosflags(ios:left)setw(10)setprecision(1)valuesi”和“”,所以,ifstream流(类对象)可以使用预定义的算符“”来对自定义磁盘文件进行“读”操作(允许通过派生类对象直接调用其基类的公有成员函数);ofstream类由ostream类所派生,而ostream类中预定义了公有的运算符重载函数“operator”,所以,ofstream流(类对象)可以使用预定义的算符“”和“”来进行“读”操作时遇空格或换行均结束一个数据相呼应。下述示例程序做了如下3件事:1)往文件写数据;2)往文件尾部追加数据;3)从文件读出数据并显示在屏幕上。,读写操作,09:10:13,54/99,#includeintmain()/1)往文件写数据ofstreamoutfile1(“myfile1.txt”);/以“写”方式打开outfile1str1str2;/使用“”读(遇空格、换行均结束)infile1x2y2;infile1.close();,09:10:13,55/99,cout“str1=”str1endl;cout“str2=”str2endl;cout“x2=”x2endl;cout“y2=”y2endl;/程序执行后的显示结果如下:str1=Hello!.CHINA!str2=CUITx2=1212y2=6868,09:10:13,56/99,1类成员函数get与put2类成员函数read与write3类成员函数getline,使用类成员函数对文件流进行操作,09:10:13,57/99,ostream功能:从自定义文件中读出1个字符放入引用rch中。注意,put实际上只是ostream类中定义的公有成员函数,当然通过其派生类ofstream的类对象也可以直接对它进行调用。同理,通过ifstream的类对象可以直接调用get。,用类成员函数get与put,09:10:13,58/99,程序示例从键盘输入任一个字符串,通过put将其写到自定义磁盘文件“putgetfile.txt”中,而后再使用get从该文件中读出所写串并显示在屏幕上。#include#includevoidmain()/键盘输入字符串,通过put将其写到自定义磁盘文件中charstr80;coutInputstring:endl;gets(str);ofstreamfout(putgetfile.txt);inti=0;while(stri)fout.put(stri+);fout.close();cout-endl;,09:10:13,59/99,/而后使用get从文件中读出该串显示在屏幕上charch;ifstreamfin(putgetfile.txt);fin.get(ch);while(!fin.eof()/从头读到文件结束(当前符号非文件结束符时继续)/注:成员函数eof()在读到文件结束时方返回truecoutch;fin.get(ch);coutendl;fin.close();/程序执行后的显示结果如下:Inputstring:Fileoperating-usingputandget,OK!12345-Fileoperating-usingputandget,OK!12345,09:10:13,60/99,程序示例对指定文件进行拷贝使用类成员函数get与put对指定文件进行拷贝。被拷贝的“源文件”以及拷贝到的“目的文件”的名字与路径均由命令行参数来提供。程序执行结果(若提供的命令行参数为:mycopy.cppres_1.cpp):Copyfilefrommycopy.cpptores_1.cpp程序执行结果(若提供的命令行参数个数不对时):ERROR!-supplying2command-lineargements?!,09:10:13,61/99,#includevoidmain(intargc,char*argv)if(argc!=3)/命令行参数个数不对时coutERROR!-supplying2command-lineargements?!endl;exit(1);coutCopyfilefromargv1toargv2endl;ifstreamfin(argv1);/命令行参数1作为文件名ofstreamfout(argv2);/命令行参数2作为文件名charch;fin.get(ch);while(!fin.eof()/从头读到文件结束fout.put(ch);fin.get(ch);fin.close();fout.close();,09:10:13,62/99,类成员函数read与write,通常使用read与write对二进制文件(binaryfile)进行读写。ostream功能:从某个文件中读入nCount个字符放入pch缓冲区中(若读至文件结束尚不足nCount个字符时,也将立即结束本次读取过程)。注意:使用write与read进行数据读写时,不必要在数据间再额外“插入”分割符,这是因为它们都要求提供第二实参来指定读写长度。,09:10:13,63/99,以下的示例程序先使用write往自定义二进制磁盘文件中写出如下3个“值”:字符串str的长度值Len(一个正整数)、字符串str本身、以及一个结构体的数据,而后再使用read读出这些“值”并将它们显示在屏幕上。#includeintmain()charstr20=Helloworld!;structstucharname20;intage;doublescore;ss=“wujun”,19,91.5;,09:10:13,64/99,coutWRITEtowrt_read_file.binwujun,19,91.5-,09:10:13,66/99,最常用格式为:istream功能:从某个文件中读出一行(至多nCount个字符)放入pch缓冲区中,缺省行结束符为n。程序实例:读出“getline.cpp”的各行并显示在屏幕上(如,可将本源程序存放在“getline.cpp“文件中)。,类成员函数getline,09:10:13,67/99,#includeintmain()charline81;ifstreaminfile(“getline.cpp”);/打开文件用于读/读出一行(至多80个字符)放入line中infile.getline(line,80);while(!infile.eof()/尚未读到文件结束则继续循环(处理)coutlineendl;/显示在屏幕上infile.getline(line,80);/再读一行infile.close();,09:10:13,68/99,text文件与binary文件对text文件与binary文件的一般使用示例采用binary文件形式对结构体数据进行存储与读写处理-对text文件与binary文件的一般使用示例*以text形式存储,优点是具有较高的兼容性。缺点是存储一批纯数值信息时,要在数据之间人为地添加分割符;输入输出过程中,系统要对内外存的数据格式进行相应转换;另外text文件不便于对数据实行随机访问。,09:10:13,69/99,*以binary形式存储优点是便于对数据实行随机访问(每一同类型数据所占磁盘空间的大小均相同,不必在数据之间人为地添加分割符);输入输出过程中,系统不对数据进行任何转换。缺点是兼容性低。注:由程序员决定将数据存储为text文件或者binary文件两种形式之一。缺省打开方式时,默认为text文件形式。若欲使用binary文件形式,要将打开方式设为“ios:binary”。通常将纯文本信息(如字符串)以text文件形式存储,而将数值信息以binary文件形式存储。,09:10:13,70/99,示例1对两种文件进行操作将a数组中准备好的8个int型数据,分别通过算符“”依次写出到text文件ft.txt之中(注意各数据在文件中“长短”不一,且数据间必须加入分割符)。而且还通过使用类成员函数write将这相同的8个int型数据依次写出到binary文件fb.bin之中(注意各数据在文件中“长短”相同,且数据间不需要加入分割符)。另外,程序中通过使用无参的成员函数“tellp()”来获取当前已写出到各文件的位置信息,以确认每一数据在文件中所占的字节数。ostream:tellp之功能为:获取并返回“输出指针”的当前位置值(从文件首到当前位置的字节数)。,09:10:13,71/99,#includeintmain()inta8=0,1,-1,1234567890;for(inti=4;i8;i+)ai=876543210+i-4;/均由9位数字组成,在text文件中所占字节数也为9ofstreamft(ft.txt);ofstreamfb(fb.bin,ios:binary);for(i=0;i8;i+)ftai;/数据间需要添加分割符fb.write(char*)(,09:10:13,72/99,/程序执行后的输出结果如下:ft.tellp()=2,fb.tellp()=4ft.tellp()=4,fb.tellp()=8ft.tellp()=7,fb.tellp()=12ft.tellp()=18,fb.tellp()=16ft.tellp()=28,fb.tellp()=20ft.tellp()=38,fb.tellp()=24ft.tellp()=48,fb.tellp()=28ft.tellp()=58,fb.tellp()=32,09:10:13,73/99,示例2使用read与write对text文件进行操作时可能出错具体程序从略。评注:(1)通常使用read与write对二进制文件进行操作,但若非要使用它们对文本文件进行操作时,系统在write时有可能多写出了一些东西(如,回车换行符号等)。这样将导致read时产生错误。(2)read与write功能的进一步解释:istream:readExtractsbytesfromthestreamuntilthelimitnCountisreachedoruntiltheendoffileisreached.Thereadfunctionisusefulforbinarystreaminput.ostream:writeInsertsaspecifiednumberofbytesfromabufferintothestream.Iftheunderlyingfilewasopenedintextmode,additionalcarriagereturncharactersmaybeinserted.Thewritefunctionisusefulforbinarystreamoutput.,09:10:13,74/99,文本文件的读与写,例7#includeintmain()inti,age;doublescore;charname8,buff20;fstreamf1;f1.open(f1.txt,ios:out);if(!f1)/!是重载运算符coutagescore;coutname;,运行结果:a1990b2088文件内容:a1990b2088,09:10:13,75/99,例8/*使用put(),get()函数进行文件的读/写。*/#include#includeintmain()fstreamf1,f2;f1.open(f1.txt,ios:in);if(!f1)coutCantopenfile.n;abort();f2.open(f2.txt,ios:out);if(!f2)coutCantopenfile.n;abort();,charc;f1.get(c);while(!f1.eof()f2.put(c);f1.get(c);f1.close();f2.close();,文本文件的读与写,09:10:13,76/99,例9向文件输出#includeusingnamespacestd;structDateintmo,da,yr;intmain()Datedt=6,10,92;ofstreamtfile(date.dat,ios:binary);tfile.write(char*),磁盘文件,09:10:13,77/99,二进制文件的读与写,对二进制文件进行读/写时,可用get()或put()这样的成员函数一次读写一个字节,也可使用write()和read()函数可一次读/写多个字节。,磁盘文件,09:10:13,78/99,二进制输出文件,以通常方式构造一个流,然后使用setmode成员函数,在文件打开后改变模式。使用ofstream构造函数中的模式参数指定二进制输出模式使用二进制操作符代替setmode成员函数:ofsn;/个数n由用户指定,09:10:13,85/99,ofstreamfout(f01.bin,ios:binary);/打开二进制文件(写)for(inti=0;ss.agess.score;fout.write(char*)(,09:10:13,86/99,示例1从键盘输入10个int型数,而后按输入的相反顺序输出它们。实现方法:使用binary文件,将数据存放在文件中,并使用随机访问方式读出。#includeintmain()constintn=10;intx,i;ofstreamfout(fdat.bin,ios:binary);coutx;fout.write(char*)(,09:10:13,87/99,cout=0;i-)fin.seekg(i*sizeof(int);fin.read(char*)(/程序执行后的输出结果为:Input10integers:12345678910-Theresult-10987654321,09:10:13,88/99,示例2(作为参考):使用write将多个person类型的结构体数据,写出到某个自定义二进制磁盘文件的指定位置处,而后再使用read从另外指定的位置处读出某些结构体数据并显示在屏幕上。一般程序处理模式:structpersoncharname20;intage;.ss;intrecnum;,09:10:13,89/99,ofstreamfout(f01.bin,ios:binary);while(需要继续写出)形成欲写出的结构体ss;形成recnum;/“纪录号”,如下标号,位置含义longoffs=sizeof(ss)*(recnum-1);fout.seekp(offs);fout.write(char*)(,09:10:13,90/99,例11#include#includeusingnamespacestd;intmain()structpersoncharname8;intage;doublescore;longpos;fstreamf1;structpersonst;pos=sizeof(structperson);f1.open(f1.dat,ios:in|ios:out|ios:binary);,f1.read(char*),09:10:13,91/99,例12intmain()structpersoncharname8;intage;doublescore;fstreamf1;structpersonst;f1.open(f1.dat,ios:in|ios:out|ios:binary);f1.read(char*),f1.seekp(sizeof(structperson),ios:beg);/写指针定位在第2个记录上strcpy(,www2);st.age=222;st.score=222.22;f1.write(char*),09:10:13,92/99,例13文件读二进制记录#include#includeusingnamespacestd;intmain()structdoublesalary;charname23;employee;ifstreamis(f1.dat,ios:binary|ios:out);if(is)is.read(char*),09:10:13,93/99,例14设置位置指针#include#includeusingnamespacestd;intmain()charch;ifstreamtfile(f1.dat,ios:binary|ios:out);if(tfile)tfile.seekg(8);while(tfile.good()tfile.get(ch);if(!ch)break;coutch;elsecoutERROR:Cannotopenfilef1.dat.endl;tfile.close();,09:10:13,94/99,例15读文件并显示其中空格的位置#include#includeusingnamespacestd;intmain()charch;ifstreamtfile(payroll,ios:binary|ios:out);if(tfile)

温馨提示

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

评论

0/150

提交评论