下载

2下载券

加入VIP
  • 专属下载特权
  • 现金文档折扣购买
  • VIP免费专区
  • 千万文档免费下载

上传资料

关闭

关闭

关闭

封号提示

内容

首页 C++课件--薛景瑄chapter_8

C++课件--薛景瑄chapter_8.doc

C++课件--薛景瑄chapter_8

jingernanhang
2018-09-05 0人阅读 举报 0 0 暂无简介

简介:本文档为《C++课件--薛景瑄chapter_8doc》,可适用于IT/计算机领域

第八章:将“课程总结”§“格式化输出”中的部分内容加入“chapterdoc”。第八章输入输出流(input/outputstream)预定义类型的输入/输出基本情况及其优点C输入输出流的优点:(一)重载运算符“<<”和“>>”能以函数重载的形式极大地扩大用途在输入输出流中充分体现多态性。C语言的输入/输出系统本来就灵活性大、功能比较完善。但它有一个较大缺点:无法处理众多的用户自定义数据类型(主要是类及其对象)。例如有一个结构类型exampl如下:structexampl{intjcharstr}strex如欲输出此结构对象strex的两个成员的内容因而笼统地使用如下输出语句printfprintf(“exampl”,strex)则将会出现编译错误。而C的输出输入系统则能很好地解决这个问题。(二)类型安全(typesafe)例C语言输出语句中的类型错误(第一章已看过)#include<stdioh>voidmain(){inti=doubled=printf(“dtfn”,i,d)}运行结果:对!但如写错为:printf(“dtdn”,i,d)则编译时不出错但运行结果错为:-但如写cout<<i<<“”<<d<<endl则得对!始终不会出错!(三)通过缓存增加功能。(四)附带优点是书写方便以及显示中没有冗余字符能自动略去尾数中的零(但如用户希望显示多余的零也可以做到)。C的输入/输出系统是对流的操作也即操作数据使其流向对象或从对象流出。什么是流?流是从源头到目的的数据流动。当键入字符时字符从键盘流入程序中当将数据写入磁盘文件中时数据流动至磁盘上。C输入/输出流库是使用继承方法建立起来的一个输入/输出类库它具有两个平行的基类即streambuf类和ios类。所有其它流类都是从它们直接或间接地派生出来的。streambuf类用于提供物理设备的接口它提供缓冲或处理流的通用方法。它作为一个虚基类具有类层次如下:图ios类及其派生类用于为用户提供使用流类的接口。它使用streambuf完成检查错误的格式化输入/输出操作并支持对streambuf的缓冲区进行输入/输出时的格式化或非格式化转换。ios类作为流库中的一个虚基类派生出许多派生类其主要层次如下:图预定义流(标准流)预定义输出输入流涉及较多的头文件有四个:ioshistreamhostreamh和iostreamh。下dlcout<<"Floatingpointnumber:"cout<<<<endlcout<<"Inscientificformat:"coutsetf(ios::scientific)cout<<<<endl}*Results:defaultxfill:(注:此处是空格)defaultxwidth:(在显示时按照实际需要显示)defaultxprecision:xwidth=#####Floatingpointnumber:Inscientificformat:e*width的缺省值是。它并不真等于零而其实际显示宽度就是数据本身长度以便按需要显示。请注意:每次显示操作后width的值被自动复位为零。其中“显示精度precision”规定浮点数的显示位数它的缺省值(默认值)是表示小数点前后共显示位(不包括小数点本身当被显示值小于时则精度只包括小数点后的字符数)。详见附录二十二。()为浮点数设置小数点显示格式:一般情况下当浮点数具有整数值并且使用流输出运算符“<<”显示该数值时并不显示小数点及其后面的。如欲显示小数点及其后面的可设置小数点格式使用showpoint控制位。控制小数点显示格式的是ios类中的公有数据成员:“showpoint位”。设置小数点显示功能的成员函数有:coutsetf(ios::showpoint)撤销小数点显示功能的成员函数有:coutunsetf(ios::showpoint)例设置小数点显示功能之一outcppusing"showpoint"todisplay'safterdecimalpoint#include<iostreamh>voidmain(){inti=doubled=coutsetf(ios::showpoint)coutprecision()cout<<i<<""<<d<<endl}*Results:*例设置小数点显示功能之二:使用固定点(fixed)格式outcppusing"fixed"todisplay'safterdecimalpoint#include<iostreamh>voidmain(){inti=,j=doubled=coutsetf(ios::fixed)coutprecision()cout<<i<<""<<j<<""<<d<<endl}*Results:*此处控制小数点显示格式的也是ios类中的公有数据成员:“fixed位”。注意:使用此格式时显示精度的定义是不同的(表示小数点以后的位数)。()对齐方式(modeofjustification)的控制可使用adjustfield。这是ios类中的一个数据成员即:staticlongadjustfieldleft|right|internal其省缺值是向右对齐。adjustfield必须和coutwidth()合用。不然无意义。例改变对齐方式formatiocpptoimproveapartofLv'sbook,p#include<iostreamh>voidmain(){doubled=coutwidth()coutfill('*')cout<<d<<endldefaultprecisionis缺省方式是向右对齐coutsetf(ios::left,ios::adjustfield)coutwidth()cout<<d<<endlcout<<d<<endl}*Results:*******使用操纵函数和操纵符以上使用ios类成员函数时无法级联调用也即无法将ios类成员函数嵌入到输入输出语句中。本节中使用操纵函数时就能将操纵函数嵌入到输入输出语句中。操纵符(manipulator)和操纵函数是在系统头文件iomaniph中定义的其中操纵函数有:…resetiosflags(longl)…setfill(inti)…setiosflags(longl)…setprecision(inti)和…setw(inti)而标准操纵符则有:dec、hex、oct、ws、endl、ends和flush。另外在头文件iomaniph已有:#include<iostreamh>所以如果程序中已包含了iomaniph头文件就不必再包含iostreamh头文件。例使用操纵函数将输入输出格式化formatiocppFromWang'sbook,pwithmistakescorrected#include<iomaniph>#include<iostreamh>已包含在iomaniph头文件中voidmain(){cout<<""<<endl标尺cout<<<<setiosflags(ios::scientific)<<setw()<<<<endlcout<<setw()<<<<<<endlcout<<<<setw()<<hex<<<<setw()<<oct<<<<endlcout<<resetiosflags(ios::scientific)<<setprecision()<<<<endl}*Results:e(隔个空格)(前有个空格)b(隔个和个空格)(如仍为scientific格式则显示e)*例将不同显示精度的运算结果排列成表formatiocppformattedIOasatable#include<iomaniph>voidmain(){inti=doubled=,f=cout<<i<<setw()<<d<<setw()<<f<<endldefaultprecisioniscoutprecision()cout<<i<<setw()<<d<<setw()<<f<<endlcoutprecision()cout<<i<<setw()<<d<<setw()<<f<<endl}*Results:e*以上程序中浮点数的显示方式有二:()当显示精度大于或等于该浮点数的整数部分的数值位数时它被正常显示。()当显示精度小于它的整数部分的数值位数时或当规定使用科学显示方式(scientific)时它被显示为一个指数如e。用户自定义操纵符用户可将数个操纵符合并定义为一个自定义操纵符以便于调用。例自定义输出操纵符ioovrcppoverloadedmanipulatorpartofprogramonp,Wang'sbook#include<iomaniph>ostreamovrmani(ostreamoutput)ostreamovrmani(ostreamoutput)error:'ostream::ostream':cannotaccessprotectedmemberdeclaredinclass'ostream'{output<<setw()<<setprecision()<<setfill('*')returnoutput}voidmain(){inti=doubled=,f=cout<<ovrmani<<i<<ovrmani<<d<<ovrmani<<f<<endl}*Results:*************此处自定义输出操纵符ovrmani()的返回值必须是ostream类对象的引用。因如不是引用而是对象本身则返回时须在栈区内建立临时对象并调用构造函数但ostream类的构造函数的访问属性是protected不允许外部函数访问不然将会出错如程序中所示。现在使用ostream类对象的引用它实际上是指针而又不必建立对象。类似情况请参阅第四章§一节中的例“将派生类中某些继承数据的私有性质改变为公有性质”中的程序derconscpp。例自定义输入/输出操纵符ioovrcppoverloadedmanipulatormodifiedprogramonp,Wang'sbook#include<iomaniph>ostreamovrmanio(ostreamoutput){output<<setw()<<setprecision()<<setfill('*')returnoutput}istreamovrmanii(istreaminput){cout<<"Pleaseinputaninteger:"returninput}voidmain(){inti=cout<<ovrmanio<<i<<endlcin>>ovrmanii>>icout<<ovrmanio<<i<<endl}*Results:*****Pleaseinputaninteger:**********用户自定义数据类型的输入/输出iostreamh头文件中所有重载的运算符函数”<<”和”>>”的返回值都是ostream类或istream类对象的引用其目的是实现级联调用(cascadedinvocation)即通过对象引用(实质上是对象指针)来连续调用这些运算符而不必建立这些类的临时对象。系统将它们定义为许多重载运算符函数但却都只用于预定义数据类型。如用户希望将该运算符函数用于用户自定义数据类型即类的对象则用户必须根据自己的需要将它们定义为更多的重载运算符函数。必须指出如果主函数希望访问对象中的私有成员则用户必须将重载的运算符函数定义为该类的友元函数而不能定义为该类的成员函数。为何?由于输入流和输出流运算符函数“>>”和“<<”分别是classistream和classostream的成员函数而不是用户自己所定义的类的成员函数。因此用户只能在自己所定义的类中将它们定义为友元函数。流输入运算符”>>”重载例流输入运算符的重载IOOVRCPPCopiedfromWangYan'sbook,p#include<iostreamh>classthree{intx,y,zpublic:three(intxi,intyi,intzi){x=xiy=yiz=zi}voidprint(){cout<<"x="<<x<<"y="<<y<<"z="<<z<<endl}friendistreamoperator>>(istreaminput,threeobj)}istreamoperator>>(istreaminput,threeobj){cout<<"Inputcoordinatesx,y,z:"input>>objxinput>>objyinput>>objzreturninput}voidmain(){threeobjthree(,,)objthreeprint()cin>>objthreeobjthreeprint()}*Results:x=y=z=Inputcoordinatesx,y,z:(由用户输入)x=y=z=*现在看一下主函数第行“cin<<objthree”的具体执行过程。此时重载运算符函数的形参input由实参cin所替代形参obj由实参objthree所替代。因此实际上用户自定义的重载运算符函数执行以下四条语句:cout<<”Inputthex,y,zofthreed:n”cin>>objthreexcin>>objthreeycin>>objthreez从而将、、分别读入objthreex、objthreey和objthreez。既然是cin运算符函数调用“operator>>()”在该重载的“operator>>()”内也可以直接使用cin而不用input例如:istreamoperator>>(istreaminput,threeobj){cout<<"Inputcoordinatesx,y,zofthree:n"cin>>objxcin>>objycin>>objzreturninput}但返回值必须是input。再看一个流输入运算符“<<”重载的例子。§“自定义输入函数”的例中的程序keyreaddblvalcpp提供了函数conv()可用于筛选掉非法字符而只输入合法字符(数码字符和小数点、空格、回车字符)。但它每次只能输入一个数据无法级联地运行例如cin<<d<<e<<f的形式。但直接使用这个形式是不可能的因为cin<<d语句中cin是classistream的派生类的对象而“<<”是其基类的成员函数两者都已有明确定义无法重新定义。为解决此问题只可采用以下两种方法之一:第一种是用户设法自定义输入流类的对象例如gin并对流输入运算符“<<”进行重载以便使用例如gin<<d<<e<<f的形式第二种是仍然使用classistream的派生类对象cin但重新定义一个新的流输入运算符例如“~~”。下例采用第一个方法。例用户自定义输入流对象gin并对流输入运算符“<<”进行重载inputconvcppuserdefinedclassobject"gin"hasnewfunctionalityintroducedasuserslikeandcanaccess">>"successivelyredundantdecimalpointscanbeignoredautomaticallywrittenbyboth薛景瑄and何海清#include<iostreamh>#include<stdlibh>fordoubleatof(constchar*)#include<conioh>forgetch()doubleconv(){charkeych,prevchchararrintn=by何海清for(inti=){keych=getch()readthelowbytekeystrokeif(n>=)by何海清{if(keych==){continue}}if(keych==||(keych==))CRkeyorspacekey{cerr<<keychif(keych==)cerr<<endlbreak}if(((keych>='')(keych<=''))||(keych==)char''||(keych==)){cerr<<keychif(keych==)nby何海清if(keych==)'backspace'key{icerr<<''<<keycheraseunwantedcharandcomebackagainif(prevch==)n=whenerasedcharis''}else{arri=keychprevch=keychforerasureof''}}}arri=''returnatof(arr)}classistreamuser{public:istreamuseroperator>>(doubled){d=conv()return*this}}ginvoidmain(){doubled=,f=cout<<d<<endl<<f<<endlcerr<<"Inputtwodoubledata:"gin>>d>>fcout<<d<<endl<<f<<endl}*Results:*以上程序所定义的classistreamuser的对象gin(getin的缩写)用于进行输入操作而其成员函数istreamuseroperator>>(doubled)被定义为流输入运算符。在定义流输入运算符“operator>>”时其返回值必须是本类对象的引用而程序末句则返回*this这才允许该运算符能被连续地调用。流输出运算符“<<”重载例流输出运算符的重载IOOVRCPP#include<iostreamh>classtele{char*namechar*numberpublic:tele(char*ptr="xue",char*ptr=""){name=ptrnumber=ptr}friendostreamoperator<<(ostreamoutput,teleobj)}ostreamoperator<<(ostreamoutput,teleobj){cout<<"name="output<<objnamecout<<endl<<"number="output<<objnumbercout<<endlreturnoutput}voidmain(){teleobjtelecout<<objtele}*Results:name=xuenumber=*在主函数第二句“cout<<objtele”的执行过程中调用了重载的运算符函数。实际上重载运算符函数的形参output由实参cout代入形参obj由实参objtele代入。因而实际上执行以下五句:cout<<"name="cout<<objtelenamecout<<endl<<"number="cout<<objtelenumbercout<<endl既然是cout运算符函数调用“operator<<()”在该重载的“operator<<()”内也可以直接使用cout而不用output例如:ostreamoperator<<(ostreamoutput,teleobj){cout<<"name="cout<<objnamecout<<endl<<"number="cout<<objnumbercout<<endlreturnoutput}但返回值必须是output的对象的引用。文件与输入/输出流文件的打开与关闭文件是存储于磁盘上的数据纪录。它是文本字符或数据字节的集合。它有两种格式:ASCII码文本(text)格式和二进制(binary)格式。无论格式如何它们的单位都是一个字节。其中文本格式可直接读取并被显示为ASCII码文本。而二进制格式文件则无法直接显示但它能够减少存储开销因它需要的空间小。以数值“”为例:文本格式需要个字节二进制格式只需个字节char*str=“”inti=ASCII‘’ASCII‘’ASCII‘’ASCII‘’ASCII‘’ASCII‘’ASCII‘’ASCII‘’ASCII‘’ASCII‘’ASCII‘’注:inti=的二进制格式值为:王燕书p提出要执行文件输入/输出操作需做三件事:()程序中应包含头文件<fstreamh>。()建立流类对象。()调用上述已经建立对象(例如out)的open()函数。先看第一步:()程序中应包含头文件<fstreamh>。我们首先查看头文件<fstreamh>它包括classfilebuf、classifstream、classofstream和classfstream四个类的接口。其中提供了三个文件流类:输入文件流类ifstream、输出文件流类ofstream、输入/输出文件流类fstream。它们的派生关系如下:图这三个流类classifstream、classofstream和classfstream的构造函数也有不同重载形式以fstream为例主要有如下四种重载形式:fstream::fstream()fstream::fstream(constchar*,int,int=filebuf::openprot)fstream::fstream(int)fstream::fstream(int,char*,int)另两个文件流类的构造函数也有这四种重载形式只是第二种形式不同为:voidifstream::ifstream(constchar*,int=ios::in,int=filebuf::openprot)voidofstream::ofstream(constchar*,int=ios::out,int=filebuf::openprot)其中filebuf::openprot是classfilebuf中的一个静态整型数据如下:classfilebuf:publicstreambuf{public:staticconstintopenprotdefaultshareprotmodeforopen……}另外在头文件fstreamh中包含了头文件iostreamh:****fstreamhdefinitionsdeclarationsforfilebufandfstreamclasses……*Purpose:*Thisfiledefinestheclasses,values,macros,andfunctions*usedbythefilebufandfstreamclasses*ATTC*……****#include<iostreamh>……因此包含头文件fstreamh时不必再包含头文件iostreamh。再看第二步:()建立流类对象。例如:ifstreaminofstreamoutfstreamfilio最后看第三步:()调用上述已经建立的流对象的open()函数将文件打开。在C中要对文件进行输入输出操作必须先将它打开。打开磁盘文件就是调用open()函数将该文件与一个文件流类对象(例如out)关联(连接)起来。例如:ofstreamoutoutopen(“test”,ios::out,)以后将进一步解释。三个文件流类的open()函数原型都包含于头文件<fstreamh>内。它们是: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)open()函数中的第一个参数“constchar*”用于传递欲打开的文件名。open()函数中的第二个参数“int”用于确定文件的打开方式必须采用以下数值中的至少一个:ios::app将输出流追加到文件末尾ios::ate寻找文件尾ios::in文件只能输入ios::nocreate不建立文件如文件不存在则open()函数操作失败ios::noreplace不替代文件如文件存在则open()函数操作失败ios::out文件只能输出ios::trunc将同名文件删除ios::binary文件以二进制方式打开如不取此值则取缺省值为文本方式对于ifstream输入流其缺省值为ios::in对于ofstream输入流其缺省值为ios::out。open()函数中的第三个参数“int”用于确定文件存取方式具有以下数值::一般文件:只读文件:隐藏文件:系统文件其缺省值为:int=filebuf::openprot(=)下面看几个例子:.打开一个输出文件:ofstreamoutoutopen(“test”,ios::out,)此处建立输出流对象outopen()函数中“test”是文件名ios::out确定文件按照输出方式被打开,表示这是一般文件。事实上此语句可简化为:outopen(“test”).打开一个输入/输出文件:fstreamfiliofilioopen(“test”,ios::in|ios::out,)此处建立输出流对象filioopen()函数中“test”是文件名ios::in|ios::out确定文件按照同时输入和输出的方式被打开,表示这是一般文件。.将两条语句合并为一条:ofstreamout(“test”)fstreamfilio(“test”,ios::in|ios::out,)此处在建立对象的同时调用open()函数。由于系统中允许同时打开文件的最大数量有限制因此一般要求文件使用完毕后加以关闭以便允许打开更多的其它文件。关闭文件的语句如下:outclose()filioclose()close()语句不带参数。关闭文件是将该文件与输入/输出流类对象之间的连接断开。因此当程序释放或删除ifstream、ofstream或fstream的输入/输出流对象时与其相关联的文件即自动关闭而该输入/输出流类对象就可用于与其它磁盘文件相关联(连接)。所以一般而言任何被打开的文件在程序结束时都会被自动关闭。文件的读写文件的顺序读写(一)文件的读操作:以前提到文件有两种格式:文本格式和二进制格式。当不知文件是何格式时可用get()函数逐个字节地读取文件。此函数在classistream中声明如下:classistream:virtualpublicios{public:……intget()用于从流中输入一个字符或EOF字符inlineistreamget(char*,int,char='n')inlineistreamget(unsignedchar*,int,char='n')inlineistreamget(signedchar*,int,char='n')用于从流中输入字符到给定的字符串char*内直至遇到隔离符(此处其缺省值为回车符)、文件结束符或已读完(第二个参数–)个字符。istreamget(char)inlineistreamget(unsignedchar)inlineistreamget(signedchar)用于从流中输入单个字符到给定的字符引用char内。istreamget(streambuf,char='n')用于从流中输入字符到给定的streambuf内直至遇到隔离符(此处其缺省值为回车符)。……}例get()函数用于读取文件fileincppfile"mydat"isreadin,nomatterwhichformatithas#include<stdlibh>#include<fstreamh>voidmain(){readfile"mydat"anddisplayitifstreamin("mydat")if(!in){cout<<"Filenotopened!"return}charchcout<<"Thefollowingisreadinanddisplayed:"<<endlcout<<'"'单引号内一个双引号while(inget(ch)){cout<<ch}cout<<'"'<<endlinclose()}*Results:Thefollowingisreadinanddisplayed:"Theseareexpectedtobeoutputtedtothefilenamedmydat"或"Wang烫藹"*此处get(ch)函数每次读取一个字节而不管其格式如何、是否能显示运行结果显示:"Theseareexpectedtobeoutputtedtothefilenamedmydat"是所读取文本文件的内容。而另一类内容例如:"Wang烫藹"则是所读取二进制文件的内容。另外在程序的语句while(inget(ch)){……}中每当从文件中读取一个字节时都循环一次。直至读到EOF(EndOfFile)时为止。此处EOF(EndOfFile)=。如果已经知道是文本文件而且内容已知例如是四个数据按顺序为:整型、浮点型、字符型和字符串。就可以使用输入流类对象来有的放矢地读取文件。例从文件中按顺序读取整型、浮点型、字符和字符串四个数据fileinCPPYoucaninputdatafromfilemydat#include<stdlibh>#include<fstreamh>voidmain(){charstrintidoubledcharchifstreamin("testdatdat")if(!in){cerr<<"Errorinopeningafile"<<endlexit()}in>>i>>d>>ch>>strcout<<i<<""<<d<<""<<ch<<""<<str<<endlinclose()}*Agood!*其中语句in>>i>>d>>ch>>str是由输入文件流类ifstream的对象in调用classifstream的直接基类classistream的成员运算符函数“>>”。正常情况下cin早已和键盘输入设备连接在一起。而现在则是in和有关文件连接在一起。因此数据就从文件流入程序的各变量中。(二)文件的写操作:同样可以按照一定顺序向文件中写入不同数据。如果已经知道是文本文件而且内容已知例如是四个数据按顺序为:整型、浮点型、字符型和字符串。就可以有的放矢地读取文件。例按顺序将整型、浮点型和字符串写入文件fileoutcppYoucanoutputtofilemydatintextformat#include<stdlibh>#include<fstreamh>voidmain(){ofstreamout("tstdat")if(outfail()){cerr<<"Errorinopeningafile"<<endlexit()}out<<<<""<<<<""<<"Wang"<<endloutclose()}*Results:(Fourdata(includingendl)aresenttofile"mydat")*此结果可用以上读取文件的程序fileincpp加以检验。其结果为:*Results:Thefollowingisreadin:"Wang"*其中语句out<<<<""<<<<""<<"Wang"<<endl是由输出文件流类ofstream的对象out调用classofstream的直接基类classostream的成员运算符函数“<<”。正常情况下cout早已和显示屏设备连接在一起。而现在则是out和有关文件连接在一起。因此数据就从程序中的各变量流出至文件中。打开输出文件时如果没有该文件则系统将自动建立一个该名称的输出文件。在文件输入中可用get()函数在文件输出中也可用put()函数。它是classostream的成员函数:classostream:virtualpublicios{public:……inlineostreamput(char)ostreamput(unsignedchar)inlineostreamput(signedchar)……}在以下程序中使用get()函数读取文件使用cout运算符函数在屏幕上显示文件内容如果必要则使用put()函数将此内容写入另一文件。在此例中主函数格式为:voidmain(intargc,char*argv){……}在调用主函数时使用命令行参数如下:C:>"copyfinfileoile"或C:>"copyfinfile"这是MSDOS(MicroSoft–DiscOperatingSystem)命令。其中三个命令行参数分别为:copyf为argv内容是程序名也即源文件名。infile为argv内容是输入文件名。textexe为argv内容是输出文件名。这三个参数是在MSDOS下键入的。例既可复制文件也可在屏幕上显示文件内容copyfcppfromZhang'sbook,pbutmodifiedYoucanusecommand"copyfinfile"todisplayinfileonscreenoryoucancopyinfiletooilebyusingcommand:"copyfinfileoile"#include<stdlibh>#include<fstreamh>voidmain(intargc,char*argv){ostream*outptr=coutoutptr指向coutThecasewhenthereisnooutputfilespecified,pointerofostreamoutptrdirectsto"cout"soastodisplayinputfileonthescreenif(argc<){cerr<<"Error,usage:copyfinfile<CR>"<<endlcerr<<"or:copyfinfileoile<CR>"<<endlexit()}ifstreaminput(argv)ifstreamobjectcreatedif(argc==)outptr=newofstream(argv)ofstreamobjectcreatedifnecessary,otherwise“outptr”stillpointsto“cout”if(!input||!outptr||!*outptr){cerr<<"Errorinopeningafile"<<endlexit()}dodisplayingorcopyingbasedonoutptrcharchwhile(inputget(ch))outptr>put(ch)“outptr”pointstoeither“cout”or“argv”if(argc==)deleteoutptrYoucan'tomitthisstatement,otherwiseoutputfilewillbeclearedwhenprogramterminates}以上程序中if(!input||!outptr||!*outptr)语句中if(!input||……||……)用于检查输入文件argv是否已经成功打开。if(……||!outptr||……)用于检查堆区分配是否成功。if(……||……||!*outptr)用于检查输出文件argv是否已经成功打开。在Windows系统下怎么输入命令行参数?可制作一个批处理(batchprocessing)命令文件例如:copyfilebat的内容可有一行(也可有很多行现在只需一行)即:filecopytestcpptextcpp或filecopytestexetextexe(这两个都是binaryfiles)调用批处理命令文件时只需在它所在的文件夹内点击它的名字即可。注意:如不在这三个文件名称copyf、infile和oile前注上路径则这三个文件必须位于同一个文件夹内。当文本数据或二进制数据或二者混同地包含于同一个对象(例如机构或类的对象或数组)内时可使用write()函数输出文件和read()函数输入文件。例用write()函数输出文件和read()函数输入文件iobinarycppAblockofdataiswrittenandread,nomatterwhichformatithas#include<fstreamh>#include<stringh>classfile{public:charnameintyearpayfile(){name=''yearpay=}file(char*arr,inti){strcpy(name,arr)yearpay=i}}voidmain(){fileobjs("Wang",),objdcout<<"source:"<<objsname<<''<<objsyearpay<<endlcout<<"destination:"<<objdname<<''<<objdyearpay<<endlofstreamout("mytstdat")if(!out){cout<<"Filenotopened!"return}outwrite((char*)objs,sizeof(file))cout<<outgcount()<<endlerror:'gcount'isnotamemberof'ofstream'outclose()ifstreamin("mytstdat")if(!in){cout<<"Filenotopened!"return}inread((char*)objd,sizeof(file))cout<<"Numberofbytesread="<<ingcount()<<endlinclose()cout<<"destination:"<<"nameis"<<objdname<<"and"<<"yearpay="<<objdyearpay<<endl}*Results:source:Wangdestination:Numberofbytesread=(bytesboundary)destination:nameisWangandyearpay=*例向盘文件mydat写入包含全部调查表的对象数组filwritcppcopiedfromMai'sbookbutmodified#include<fstreamh>#include<stringh>#include<stdlibh>forexit()constintINDEX=structperson{charnameintage}listINDEXvoidmain(){strcpy(listname,"Wang")第一个listage=strcpy(listname,"Liu")第二个listage=strcpy(listINDEXname,"Qu")最后一个listINDEXage=ofstreamoile("mytestdat")if(!oile){cerr<<"Cannotopenfile"<<endlexit()}oilewrite((char*)list,sizeof(list))oroilewrite((char*)list,INDEX*sizeof(person))oileclose()}注意:必须在同一文件夹中运行filwritexe从而建立mydat。该文件内容为:listlistlistlistlistWLQAiuNuG在向文件输出数据时还可以使用文件流(例如ofstream)对象作为函数参数其例见附录二十三。*文件的随机读写对文件进行随机读写时使用指针。在VC版本中只有一个文件指针即读指针和写指针合为一个。例对一个文件指针的控制randomcppabitsimplifiedrandomcpp#include<fstreamh>#include<stdlibh>voidmain(){fstreamfile("filedat",ios::out|ios::in|ios::binary)⑴用于读写if(!file)⑵{cout<<"failn"abort()}for(inti=i<=i)⑶loopsfilewrite((char*)i,sizeof(int))longpos=filetellp()⑷pos=cout<<"Currentpointerposition:"<<pos<<endl⑸for(i=i<=i)⑹loopsfilewrite((char*)i,sizeof(int))fileseekp(pos)⑺fileread((char*)i,sizeof(int))⑻指针=cout<<"Thedatumstored:"<<i<<endl⑼fileseekp(,ios::beg)⑽for(i=i<=i)⑾loopsfilewrite((char*)i,sizeof(int))fileseekp(pos)orfileseekg(pos)⑿指针=fileread((char*)i,sizeof(int))⒀指针=cout<<"Thedatumstored:"<<i<<endl⒁fileseekp(,ios::cur)⒂指针=fileread((char*)i,sizeof(int))⒃指针=cout<<"Thedatumstored:"<<i<<endl⒄cout<<"Currentpointerposition:"<<filetellp()<<endl⒅}*Result:Currentpointerposition:Thedatumstored:Thedatumstored:Thedatumstored:Currentpointerposition:*参见randomppt或者randomprogppt和randomresultppt,……,,↑(pos=),……,,,…………,,……,,,…………,(datum)例对文件mydat写入后又对它随机读取randomcppmodifiedexampleonLv'sbook,p#include<fstreamh>voidmain(){structstudent{charnameintnumberdoublescore}stu={"Ma",,,"Li",,,"Qu",,,"Liu",,,"Lan",,}stustustustustuMLQLLAiuiaunfstreammyfile("mydat",ios::out|ios::in|ios::binary)if(!myfile){cout<<"failureinopeningmydatn"return}for(inti=i<i)myfilewrite((char*)stui,sizeof(student))studenttempfor(){cout<<"Typeinthesequencenumberplease():"cin>>iif(i<||i>)i>=andi<=required{cout<<"Programterminated!"<<endlbreak}ifmyfileseekg((i)*sizeof(student),ios::beg)myfileread((char*)temp,sizeof(student))ithelementoffile"mydat"hasbeenreadintotempcout<<tempname<<'t'<<tempnumber<<'t'<<tempscore<<endl}formyfileclose()}*Result:Typeinthesequencenumberplease():MaTypeinthesequencenumberplease():QuTypeinthesequencenumberplease():LanTypeinthesequencenumberplease():LiTypeinthesequencenumberplease():LiuTypeinthesequencenumberplease():Programterminated!*标准IO设备的重定向(redirect)通常标准IO设备都有缺省的定向:标准输出设备定向为屏幕而标准输入设备则定向为键盘。必要时我们也可将这些标准IO设备重新定向为文件。在以下的例子中可以在执行程序的过程中将标准IO设备重新定向为任意文件从而实现文件的读写。例标准输出设备的重定向:将数据写入任意文件outdatredoutcppRedirecttheoutputstreambyusingMSDOScommand"redout>outdat"(write)or"redout>>outdat"(append)#include<iostreamh>voidmain(){cerr<<"Pleaseinputaninteger:"cerrwillnotberedirectedyoucannotusecoutintdatacin>>datacout<<data<<endl}一般在MS-DOS系统下运行!有两个命令格式第一个命令为:C:redout>outdat用于将文件outdat清除并将键入的数据输出至outdat中。*Results:Pleaseinputaninteger:(cout即将数据输出到文件outdat中)。*可检查outdat内容:C:typeoutdat其内容为:第二个命令为:C:redout>>outdat(注意:此处用两个>>)用于将数据写入文件outdat末尾但不清除文件outdat原有内容*Results:Pleaseinputaninteger:(cout即将数据输出到文件outdat末尾)。*可检查outdat内容:C:typeoutdat其内容为:(文件中原有仍然保存)请注意:这里使用的运算符是“>”和“>>”。例标准输入设备的重定向redincppRedirecttheinputstreambyusingMSDOScommand"redin<mydat"#include<iostreamh>voidmain(){intdatacin>>datacerr<<"Inputtedintegeris:"cerrwillnotberedirectedyoucannotusecoutcout<<data<<endl}同样能够在MS-DOS下运行:例如为从文件indat中读取数据并且显示出来可:C:redin<indat*Results:Inputtedintegeris:*请注意:这里使用的运算符是“<”。例标准输入/输出设备同时重定向redirectcppRedirecttheoutputandinputstreamsprocessingonlyonedatumusingMSDOScommand"redirect<indat>outdat"#include<iostreamh>voidmain(){intdatacin>>datacerr<<"Adatumhasbeentransferred!"cerrwillnotberedirectedyoucannotusecoutcout<<data<<endl}同样在MS-DOS下运行:例如为从文件indat中读取数据并且将它写入outdat可:C:redin<indat>outdat*Results:Adatumhasbeentransferred!*以上可以使用批处理命令文件(batchprocessingfile)来处理即在Windows下使用批处理命令执行。例如批处理命令文件outredbat其内容只有一条:redout>outdat以及inredbat其内容也只有一条:redin<indat又如:filcpybat其内容只有一条:copyfinfiledatoiledat以后在Windows下运行这些批处理文件即可但缺点是无法临时修改批处理命令文件例如outbat内的文件名(例如reddat)!(第八章完)iostreamistreamwithassigniosostreamwithassignfstreamistreamfstreambaseostreamfstreambaseiosconbufstrstreambuffilebufstreambufiostreamwithassignistreamostreamfstreamofstreamifstreamiostreamiostreamwithassig

用户评价(0)

关闭

新课改视野下建构高中语文教学实验成果报告(32KB)

抱歉,积分不足下载失败,请稍后再试!

提示

试读已结束,如需要继续阅读或者下载,敬请购买!

文档小程序码

使用微信“扫一扫”扫码寻找文档

1

打开微信

2

扫描小程序码

3

发布寻找信息

4

等待寻找结果

我知道了
评分:

/46

C++课件--薛景瑄chapter_8

VIP

在线
客服

免费
邮箱

爱问共享资料服务号

扫描关注领取更多福利