版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
第七章输入输出流7.1输入输出基本概念7.2标准输出流7.3标准输入流7.4对数据文件的操作与文件流*7.5字符串流7.1输入输出基本概念7.1.1输入输出的逻辑形式7.1.2输入输出的分类7.1.3输入输出的类库结构7.1.1输入输出的逻辑形式例如:当键入字符时,就可认为字符从键盘流入程序的数据结构中;当写入磁盘文件时,也可认为程序流到磁盘上。把接收存放输出数据的地方叫做目标,把输入数据来自的地方叫做源,C++将数据从源到目的端的传送形象地看做一个“流”。设备内部程序数据输入流输出流数据设备设备包括:(1)磁盘文件(2)设备文件(如键盘、显示器、打印机等)在输出输出过程中会经过内存缓冲区设备内部程序数据输入流输出流数据设备内存缓冲区内存缓冲区引入缓冲的目的是解决CPU的运行速度和外设操作速度不匹配的矛盾。如输出时先写入缓冲区,再成批输出。成批写出数据比一个一个写出数据节约时间。一般地,缓冲区在内存中。7.1.2输入输出的分类(1)标准的输入输出从键盘输入数据,输出到显示器屏幕。简称标准I/O。(2)文件的输入输出以外存磁盘文件为对象进行输入和输出,即从磁盘文件输入数据,数据输出到磁盘文件。简称文件I/O。(3)字符串输入输出对内存中指定的空间进行输入和输出。通常指定一个字符数组作为存储空间(实际上可以利用该空间存储任何信息)。这种输入和输出称为字符串输入输出,简称串I/O。7.1.3输入输出的类库结构C++把与输入和输出有关的操作定义为一个类体系,放在一个系统库里(称为流库),供用户调用。流库中的类称为流类(streamclass)。用流类定义的对象称为流对象。流类具有两个平行的基类即streambuf类和ios类,所有其它的流类都是从它们直接或间接地派生出来的。7.1.3输入输出的类库结构C++流库主要由两个流类层次组成:以streambuf类为父类的类层次主要用于管理流的缓冲区。以ios类为父类的类层次实现了各种格式化的输入/输出控制方法。1:标准I/O的流类的体系2:文件I/O的流类的体系标准I/O的流类的体系通用输出流基类通用输入输出流基类cin为istream类的对象cout、cerr、clog为ostream类的对象iosistreamiostreamostreamstreambuf一个指针成员指向该类对象通用输入流基类抽象缓冲区基类流基类需要包含头文件:iostream通用输入输出流基类文件I/O的流类的体系iosistreamiostreamostreamstreambufifstreamofstreamfstreamfilebuf完成从文件提取数据完成向文件插入数据完成提取插入操作完成文件缓冲区管理一个指针成员指向该类对象通用输出流基类通用输入流基类抽象缓冲区基类流基类需要包含头文件:fstream7.2标准输出流标准输出流是流向标准输出设备(显示器)的数据。流库中已经预先定义了cout、cerr和clog三个标准输出流对象。通过包含头文件“iostream”就可以使用这三个对象。7.2.1cout,cerr和clog流1.cout流对象2.cerr流对象3.clog流对象1cout流对象作用:可以将不同类型的数据输出到屏幕上,如:cout<<‘A’<<12.2<<15;cout对象为什么可以这样使用?因为在ostream中用运算符重载实现了多种数据类型的标准输入输出。而cout是ostream的对象。C++对基本的数据类型,均定义了重载运算符<<classostream:virtualpublicios{public:……ostream&operator<<(char*);//字符串输出重载函数……ostream&operator<<(char&);//字符输出重载函数……ostream&operator<<(int&);//
整数输出重载函数……ostream&operator<<(double&);//实型数据输出重载函数……};//此处代码仅仅是示意,实际的ostream是类模板,代码比较复杂2.cerr流对象cerr流对象是标准出错流。它不经过缓冲区直接向显示器输出出错信息。3.clog流对象
clog流对象也是标准出错流,clog是带缓冲版本的标准出错流。例7.1编写程序,从键盘输入a,b,c的值求解一元二次方程。如果a=0或判别式的值<0,输出出错信息。关于这三者的区别其实相当复杂,书上介绍的三者的区别并不完全正确,有兴趣的同学可以参考网上的分析文章:“cout/cerr/clog之异同极其重定向”“clog,cout,cerr输出机制”。输入方程的系数a,b,ca=0TF报告输入系数a的值等于0,出错!b2-4ac<0TF报告判别式的值小于0,出错!分别计算一元二次方程的两个根X1和X2。NS流程图#include<iostream>usingnamespacestd;intmain(){floata,b,c,disc;cout<<"请输入a,b,c:";cin>>a>>b>>c;if(a==0)cerr<<"a等于0,错误!"<<endl;elseif((disc=b*b-4*a*c)<0)
cerr<<"判别式b*b-4*a*c<0<<endl;else{
cout<<"x1="<<(-b+sqrt(disc))/(2*a)<<endl;
cout<<"x2="<<(-b-sqrt(disc))/(2*a)<<endl;}return0;}7.2.2格式输出在输出数据时,如不指定格式,则采用系统给定的默认格式。通过控制符或流的成员函数设置可以输出格式。1.用控制符设置输出格式表7.3列出了输出格式的控制符。这些控制符大部分在头文件iomanip中声明,另一部分控制符的声明包含在头文件iostream中。控制符是函数。所以也可以称为格式控制函数。例7.2用控制符控制输出格式。resetiosflags()#include<iostream>#include<iomanip>usingnamespacestd;intmain(){inta;cout<<"inputa:";cin>>a;cout<<"dec:"<<dec<<a<<endl;cout<<"hex:"<<hex<<a<<endl;cout<<"oct:"<<setbase(8)<<a<<endl;char*pt="China";cout<<setw(10)<<pt<<endl;cout<<setfill('*')<<setw(10)<<pt<<endl;doublepi=22.0/7.0;cout<<setiosflags(ios::scientific)<<setprecision(8);cout<<"pi="<<pi<<endl;cout<<"pi="<<setprecision(4)<<pi<<endl;cout<<resetiosflags(ios::scientific);cout<<"pi="<<setiosflags(ios::fixed)<<pi<<endl;return0;}inputa:34dec:34hex:22oct:42China*****Chinapi=3.14285714e+000pi=3.1429e+000pi=3.1429请按任意键继续...2.用流对象的成员函数控制输出格式用于控制输出格式的常用成员函数见表7.4流成员函数setf和控制符setiosflags括号中参数是格式标志,在类ios中定义它是枚举值。所以在引用这些格式标志时要以ios::开始,格式标志列于表7.5。例7.3用流控制成员函数输出数据。intmain(){inta=21;cout.setf(ios::showbase);cout<<"dec:"<<a<<endl;cout.unsetf(ios::dec);cout.setf(ios::hex);cout<<"hex:"<<a<<endl;cout.unsetf(ios::hex);cout.setf(ios::oct);cout<<"oct:"<<a<<endl;char*pt="China";cout.width(10);cout<<pt<<endl;cout.width(10);cout.fill('*');注意:用成员函数setf()设置整数的基数,必须用函数unsetf()终止后才能重新设置其他整数基数格式,否则下次设置setf()后,输出流数据又以默认的十进制基数显示。注意:用控制符setw()或者成员函数width()设置输出数据的宽度仅仅对其后的第一个数据有效。cout<<pt<<endl;doublepi=22.0/7.0;cout.setf(ios::scientific);cout<<"pi=";cout.width(14);cout<<pi<<endl;cout.unsetf(ios::scientific);cout.setf(ios::fixed);cout.width(12);cout.setf(ios::showpos);cout.setf(ios::internal);cout.precision(6);cout<<pi<<endl;return0;}7.2.3用流成员函数put输出字符格式:cout.put(字符/数字)[.put(…)……]如是字符,直接输出该字符;如是数字,可以用八进制、十进制或十六进制表示整数,用该数字对256取模,输出对应的ASCII码字符。如:cout.put('f').put(65).put(321);输出:fAA例7.4按相反的顺序输出“BASIC”。#include<iostream>usingnamespacestd;intmain(){
char*a="BASIC";for(inti=4;i>=0;i--)cout.put(*(a+i));cout.put('\n');return0;}输出:CISAB7.3标准输入流标准输入流是从标准输入设备(键盘)流向内存的数据。即从键盘读取的数据。流库中已经预先定义了cin这个标准输入流对象。通过包含头文件“iostream”就可以使用这个对象。7.3.1cin流对象7.3.2输入字符的流成员函数7.3.1cin流对象cin是istream类的对象。istream重载了基本的数据类型的流提取运算符>>,所以可以用cin>>x;这样的语句输入数据至变量x中。cin是缓冲流,当输入一行结束按回车(Enter)时,操作系统将输入内容放入输入缓冲区,然后cin从输入缓冲区提取数据。输入数据时,在缺省的情况下,数据之间的分隔符为:<Space>键(空格键)、<Tab>键(制表键)或<Enter>键(回车键),这三个键通称为空白字符。如:charc1,c2,c3;cin>>c1>>c2>>c3;程序运行时,可输入:a<Space>b<Tab>c<Enter>
也可输入:a<Tab>b<Tab>c<Enter>
或输入:a<Enter>b<Enter>c<Enter>在上述情况下,三个变量c1、c2和c3获得值均为‘a’、‘b’和‘c’。应注意,最后输入的总是回车键。当遇到无效字符(文件结束符或者与变量数据类型不一致),cin流的所有操作都被终止,cin的值变为false。可以根据cin的值判断流对象是否处于正常状态。例7.5测试cin的值,判断流对象的状态。intmain(){floatgrade;cout<<"entergrade:";
while(cin>>grade){if(grade>=85)cout<<grade<<"GOOD!"<<endl;if(grade<60)cout<<grade<<"fail!"<<endl;cout<<"entergrade:";}cout<<"Theend."<<endl;return0;}#include<iostream>usingnamespacestd;intmain(){floatgrade;while(1){cout<<"entergrade:";cin>>grade;if(cin.good()==false)break;if(grade>=85)cout<<grade<<"GOOD!"<<endl;if(grade<60)cout<<grade<<"fail!"<<endl;}cout<<"Theend."<<endl;return0;}7.3.2输入字符的流成员函数1.不带参数的get函数格式:cin.get()函数的类型是字符,函数的功能是从输入流中提取一个字符作为函数值返回。如在流中遇到文件结束符时(在键盘中输入ctrl+z),返回-1。例7.6用get函数读入字符。intmain(){charc;cout<<"enterasentence:"<<endl;
while((c=cin.get())!=EOF)cout.put(c);return0;}2.带一个参数的get函数格式:cin.get(字符变量)功能:从输入流中提取一个字符赋予字符变量。如遇到文件结束符就返回0。例7.6.2把例7.6改写如下:intmain(){charc;cout<<"enterasentence:"<<endl;
while(cin.get(c)){cout.put(c);}cout<<"end"<<endl;return0;}^Z表示ctrl+Z3.带三个参数的get函数格式:cin.get(字符指针,n,终止字符)作用:输入字符串函数从键盘缓冲区提取n-1个字符,顺序放入字符指针所指的字符数组。如果在提取过程中遇到终止字符,则终止提取。终止字符默认为’\n’在提取的最后一个字符位置后会添加字符串结束标志’\0’。例7.6.3intmain(){charch[20];cout<<"enterasentence:"<<endl;cin.get(ch,10,‘\n’);//与cin.get(ch,10)相同cout<<ch<<endl;return0;}
cin.get()中不带参数和只带一个参数的函数,都是以文件结束符作为终止提取的控制符(输入ctrl+z)。如果提取一个字符结束会把指针移到下一个字符。
cin.get()中带三个参数的函数,以字符个数或者“终止提取字符”为终止提取的控制符。如遇到终止提取字符而终止提取的,则提取字符结束后指针会指向“终止提取字符”。cin.get()函数族不忽略提取的空白字符。#include<iostream>usingnamespacestd;intmain(){charch[20];chara;
cin.get(ch,10,'/');cin.get(a);cout<<ch<<endl;cout<<a;return0;}输入情况一:1234567890输出结果:1234567890输入情况二:123456/789输出结果:123456/4.用成员函数getline读入一行字符格式:cin.getline(字符指针,n,终止字符)函数功能与带三个参数的get函数类似:相同点:它们都不忽略提取过程中遇到的空白字符,当遇到终止字符时或者达到字符个数上限时就停止提取。终止字符的默认值是’\n’;区别:1:停止提取时,cin.getline会把指针移到终止字符后相邻的字节,而带三个参数的cin.get函数不会。2:当在遇到终止字符前已经达到字符个数时,cin.getline会把cin的状态置为错误,而cin.get不会。cin的状态可以用cin.good()得到,1表示正常,0表示错误。intmain(intargc,char*argv[]){ charch[20]; charc1;cout<<"输入一句话:"<<endl;cin>>ch;cout<<"第一次cin提取的字符串是:"<<ch<<endl;c1=cin.get();cout<<"第二次cin.get()提取的字符串是:"<<c1<<endl;cin.get(c1);cout<<"第三次cin.get(c1)提取的字符串是:"<<c1<<endl;cin.get(ch,20,'/');cout<<"第四次cin.get(ch,20,'/')提取的字符串是:"<<ch<<endl;cin.getline(ch,20,'/');cout<<"第五次cin.getline(ch,20,'/')提取的字符串是:"<<ch<<endl;cin.getline(ch,20,'/');cout<<"第六次cin.getline(ch,20,'/')提取的字符串是:"<<ch<<endl;return0;}#include<iostream>usingnamespacestd;intmain(){charch[20];chara;cin.getline(ch,10,'/');cout<<"cinstate:"<<cin.good()<<endl;cin.get(a);cout<<"ch:"<<ch<<endl;cout<<"a:"<<a<<endl;return0;}输入情况一:1234567890输出结果:cinstate:0ch:123456789a:请按任意键继续...输入情况二:123456/789输出结果:cinstate:1ch:123456a:7请按任意键继续...cin>>与cin.getline的区别
cin>>和cin.getline都具有从键盘缓冲区按指针所指提取字符串的功能。它们有以下区别:(1)cin>>忽略起始的空白字符;而cin.getline不忽略起始的空白字符。(2)cin>>当提取到非空白字符后,遇到空白字符时就终止提取,指针就停留在空白字符处;而cin.getline是提取到规定的终止字符或规定的字符个数后终止提取,指针停留在提取的最后一个字符后面相邻的字节。(3)通过对>>的重载,cin可以提取其他类型的数据;而cin.getline只能输入字符串。例7.7用成员函数getline读入一行字符。#include<iostream>usingnamespacestd;voidmain(){charch[20];cout<<"输入一句话:"<<endl;cin>>ch;cout<<"第一次cin提取的字符串是:"<<ch<<endl;cin.getline(ch,20,'/');cout<<"第二次cin.getline提取的字符串是:"<<ch<<endl;cin.getline(ch,20);cout<<"第三次cin.getline提取的字符串是:"<<ch<<endl;}#include<iostream>usingnamespacestd;voidmain(){charch[20];cout<<"输入一句话:"<<endl;cin>>ch;cout<<"第一次cin提取的字符串是:"<<ch<<endl;cin.get(ch,20,'/');cout<<"第二次cin.get提取的字符串是:"<<ch<<endl;cin.getline(ch,20);cout<<"第三次cin.getline提取的字符串是:"<<ch<<endl;}7.3.3istream类其他函数
eof()函数当输入缓冲区的指针遇到文件结束符时函数值为真,否则显假。从键盘用ctrl+z输入文件结束符。例7.8从键盘输入字符串,以文件结束符作为结束标志,逐个输出非空格字符。#include<iostream>usingnamespacestd;voidmain(){charc;while(!cin.eof())if((c=cin.get())!='')//cout.put(c);cout<<c;}当(!cin.eof())(c=cin.get())!=''TF输出C7.4文件操作和文件流7.4.1ASCII文件和二进制文件ASCII文件ASCII文件就是文本文件,每个字节表示一个字符,将内存中的数据按照字符的ascii码形式存放到磁盘中(以可阅读的形式将信息保存)。二进制文件二进制文件是把内存中的数据、指令按其在内存的格式存放在磁盘上。异同点:字符信息在内存也是以ASCII码形式存放,所以字符在ASCII码文件和在二进制文件中形式是一样的。对于数值数据,两者是不一样的。数值的两种文件保存方法举例例如,一个十进制长整数100000,在内存中以四个字节存储;保存成二进制文件:把这4个字节内容原样写到文件中。保存成ASCII文件:保存字符1和5个字符0的ascii码到文件中7.4.2ASCII文件操作
——写文件以输出方式打开文件用流插入符写文件关闭文件一个例子:ofstreamoutfile(“data.txt",ios::out);outfile<<100<<endl;outfile<<99.01<<endl;outfile<<"helloworld!"<<endl;outfile.close();#include<fstream>usingnamespacestd;intmain(){
ofstreamoutfile("data.txt",ios::out);outfile<<100<<endl;outfile<<99.01<<endl;outfile<<"helloworld!"<<endl;outfile.close();return0;}以上程序会在程序当前路径上创建文件data.txt,然后在文件中写上如下数据:10099.01helloworld!//文件输出流对象ofstream在//文件fstream中声明7.4.2ASCII文件操作
——写文件练习:定义三个变量:英语成绩,数学成绩,语文成绩,由用户输入此三个数字,然后将这三个成绩保存到文件data.txt中以空格隔开。#include<fstream>//声明流对象ofsteam的头文件#include<iostream>//声明流对象cout和cin的头文件usingnamespacestd;intmain(){
ofstreamoutfile(“data.txt”,ios::out);//定义并打开一个输出文件流对象floatscoreEng,scoreMath,scoreChn;cout<<"请输入英语成绩"<<endl;cin>>scoreEng;cout<<"请输入数学成绩"<<endl;cin>>scoreMath;cout<<"请输入语文成绩"<<endl;cin>>scoreChn;outfile<<scoreEng<<''<<scoreMath<<''<<scoreChn<<endl; outfile.close();return0;}7.4.2ASCII文件操作
——写文件注意:用ios::out方式打开一个输出文件,若没有该文件,则会先创建一个新的文件。若已有此名字的文件,则会首先清除原有内容。举例:想将文件data.txt中的内容清空。#include<fstream>//声明流对象ofsteam的头文件usingnamespacestd;intmain(){
ofstreamoutfile("data.txt",ios::out);//定义并打开一个输出文件流对象 outfile.close();return0;}设想一下这样一种情景:程序在某一文件中写入了一些数据。程序关闭后,这时候操作者发觉少录入了一些数据,需要往文件中再继续写入一些数据。这时候不能用ios::
out方式打开文件写文件。需要用追加写的方式。7.4.2ASCII文件操作
——追加写文件以追加输出的方式打开文件用流插入符写文件关闭文件一个例子:假设文本文件data.txt中的数据为:10099.01helloworld!ofstreamoutfile(“data.txt",ios::app);outfile<<200<<''<<100.01<<''<<"helloworld!"<<endl;outfile.close();#include<fstream>usingnamespacestd;intmain(){ofstreamoutfile("data.txt",ios::app);//追加输出方式outfile<<200<<''<<100.01<<''
<<"helloworld!"<<endl;outfile.close();return0;}以上程序会在文件data.txt末尾添加数据,程序运行后文件中的内容如下:10099.01helloworld!200100.01helloworld!//文件输出流对象ofstream在//文件fstream中声明用ios::app方式打开一个输出文件,会将文件指针设置到文件末尾,写文件的时候从文件末尾开始添加数据。若文件不存在,则会先创建一个新的文件。7.4.2ASCII文件操作
——读文件以输入方式打开文件用流提取符读文件关闭文件一个例子:假设文本文件中的数据为10099.01helloworld!ifstreaminfile("data.txt",ios::in);intnum1;infile>>num1;doublenum2;infile>>num2;chartext[20];infile>>text;infile.close();#include<fstream>#include<iostream>usingnamespacestd;intmain(){
intnum1;doublenum2;chartext[20];
ifstreaminfile("data.txt",ios::in);infile>>num1;infile>>num2;infile>>text;infile.close();cout<<num1<<''<<num2<<''<<text<<endl;return0;}以上会输出:10099.01helloworld!//文件输出流对象ifstream在//文件fstream中声明7.4.2ASCII文件操作
——读文件练习:假设文本文件“data.txt”中的内容为:858095请定义三个变量:英语成绩,数学成绩,语文成绩,将文件中的数据依次读到这三个变量中,显示这三个成绩的值。#include<fstream>
//声明流对象ofsteam的头文件#include<iostream>
//声明流对象cout和cin的头文件usingnamespacestd;intmain(){
floatscoreEng;
floatscoreMath;
floatscoreChn;
ifstreaminfile(“data.txt”,ios::in);//定义并打开一个输出文件流对象
infile>>scoreEng;
infile>>scoreMath;
infile>>scoreChn;
infile.close();
cout<<scoreEng<<''<<scoreMath<<''<<scoreChn<<endl;
return0;}7.4.2ASCII文件操作
——其它一些细节1:文件打开的两种方式方法一:定义文件流对象的同时指定参数,如:
ifstreaminfile("data.txt",ios::in);方法二:调用文件流对象的成员函数open,如:ifstreaminfile;infile.open("data.txt",ios::in);2:可以调用文件流对象的put,get,getline成员函数进行读写。如:chartext[51];ifstreaminfile("data.txt",ios::in);infile.getline(text,50);//将文件data.txt中的第一行读到text数组中。3:文件流对象的流插入和流提取运算符支持标准类型的数据。对于自定义的类类型数据的文件输入输出操作则需要自定义“运算符重载”函数。该重载函数通常以外部函数实现。7.4.2ASCII文件操作
——其它一些细节4:检测文件打开是否失败的方法有一些情况会造成文件打开失败,典型的两种情况如下:情况一:输出方式打开一个文件时,若文件是只读属性的。判断方法:若文件打开失败,则文件流对象的类型转换函数返回false,否则返回true。情况二:输入方式打开一个文件时,若文件不存在。#include<fstream>#include<iostream>usingnamespacestd;intmain(){
ofstreamoutfile("data.txt",ios::out);
if(!outfile){cerr<<"Fileopenerror"<<endl;return-1;}outfile<<"helloworld!"<<endl;outfile.close();return0;}系统会自动转为这种执行方式:!(outfile.operatorbool())当data.txt文件的属性为只读时,文件打开失败,程序会输出:Fileopenerror7.4.2ASCII文件操作
——综合举例例子:成绩的输入与输出。1:定义一个成绩类,包括数据成员:学号(字符串),英语成绩,数学成绩,语文成绩;包括一个带参数的构造函数和成绩显示函数。2:定义两个外部函数,分别重载文件流插入和流提取运算符。3:定义一个主函数:其中先定义一个成绩对象,将该对象的数据写入文件中,再定义另外一个成绩对象,将文件中的数据读取到新定义的这个成绩对象。显示这两个对象的信息。成绩类命名为Score,类图结构如右边所示。id:学号scoreChn:语文成绩scoreEng:英语成绩scoreMath:数学成绩display:成绩显示成员函数Score:构造函数#include<fstream>#include<iostream>usingnamespacestd;classScore{private:charid[20];floatscoreEng,scoreMath,scoreChn;public:Score(char*id,floateng=0,floatmath=0,floatchn=0):scoreEng(eng),scoreMath(math),scoreChn(chn){strcpy(this->id,id);}voiddisplay(){cout<<"学号:"<<id<<endl<<"英语成绩:"<<scoreEng<<endl<<"数学成绩:"<<scoreMath<<endl<<"语文成绩:"<<scoreChn<<endl;}}
下一步要定义两个外部运算符重载函数,需要访问类的私有成员,怎么办?将外部函数定义为类的友元。
friendofstream&operator<<(ofstream&outfile,Score&score);friendifstream&operator>>(ifstream&infile,Score&score);};ofstream&operator<<(ofstream&outfile,Score&score){outfile<<score.id<<''<<score.scoreEng<<''<<score.scoreMath<<''<<score.scoreChn;//在每个数据之后增加一个空格使得数据有分割returnoutfile;}ifstream&operator>>(ifstream&infile,Score&score){infile>>score.id>>score.scoreEng>>score.scoreMath>>score.scoreChn;returninfile;}1:为什么要返回流对象,可不可以不返回值?复习一下流运算符重载时的一些问题:为了进行连续流插入或者流提取操作,如outfile<<score1<<score2;2:为什么不能定义为类的成员函数。双目运算符在重载为类的成员函数后,在使用时左操作数必须为类对象。即需要这样写score1<<outfile。不符合习惯用法。3:参数为何使用引用类型?若定义为类类型,则会调用拷贝构造函数生成新的对象,增加了程序的开销。intmain(){Scorescore1(“0”,80,90,70),score2(“1”);//定义两个成绩对象
ofstreamoutfile(“data.txt”,ios::out);//定义一个文件输出流对象if(!outfile)//若打开失败则结束程序{cout<<"FileopenError"<<endl;return-1;}outfile<<score1;//成绩对象1写文件outfile.close();ifstreaminfile(“data.txt”,ios::in);//定义一个文件输入流对象if(!infile)//若打开失败则结束程序{cout<<"FileopenError"<<endl;return-1;}infile>>score2;//将数据读到成绩对象2中
infile.close();score1.display();score2.display();return0;}程序输出结果:学号:0英语成绩:80数学成绩:90语文成绩:70学号:0英语成绩:80数学成绩:90语文成绩:707.4.3二进制文件操作read成员函数和write成员函数的原型分别是:istream&read(char*bu,intlen);ostream&write(constchar*bu,intlen);字符指针bu指向内存要读或写的数据起始位置。len是一次要读写的数据字节个数(数据长度)。调用格式:输入文件流对象.read(内存首地址,字节数);
输出文件流对象.write(内存首地址,字节数);二进制文件不用流插入运算符和流提取运算符读写文件,而用成员函数read和write读写文件。7.4.3二进制文件操作
——写文件以二进制方式打开文件用成员函数write写文件关闭文件一个例子:ofstreamoutfile(“data.bin”,ios::binary);intnum1=100;doublenum2=99.01;chartext[20]="helloworld!";outfile.write((char*)&num1,sizeof(int));outfile.write((char*)&num2,sizeof(double));outfile.write((char*)text,sizeof(text));outfile.close();#include<fstream>usingnamespacestd;intmain(){intnum1=100;doublenum2=99.01;chartext[20]="helloworld!";
ofstreamoutfile("data.bin",ios::binary);outfile.write((char*)&num1,sizeof(int));outfile.write((char*)&num2,sizeof(double));outfile.write((char*)text,sizeof(text));outfile.close();return0;}以上程序会在程序当前路径上创建文件data.bin,然后在文件中将num1,num2,text在内存中的二进制数据写入文件。//文件输出流对象ofstream在//文件fstream中声明7.4.3二进制文件操作
——写文件练习:定义三个变量:英语成绩,数学成绩,语文成绩,由用户输入此三个数字,然后将这三个成绩保存到二进制文件data.bin中。#include<fstream>//声明流对象ofsteam的头文件#include<iostream>//声明流对象cout和cin的头文件usingnamespacestd;intmain(){
ofstreamoutfile(“data.bin”,ios::binary);//定义并打开一个输出文件流对象floatscoreEng,scoreMath,scoreChn;cout<<"请输入英语成绩"<<endl;cin>>scoreEng;cout<<"请输入数学成绩"<<endl;cin>>scoreMath;cout<<"请输入语文成绩"<<endl;cin>>scoreChn;outfile.write((char*)&scoreEng,sizeof(float));outfile.write((char*)&scoreMath,sizeof(float));outfile.write((char*)&scoreChn,sizeof(float));outfile.close();return0;}7.4.3二进制文件操作
——写文件注意:用ios::binary方式打开一个输出文件,若没有该文件,则会先创建一个新的文件。若已有此名字的文件,则会首先清除原有内容。举例:想将文件data.bin中的内容清空。#include<fstream>//声明流对象ofsteam的头文件usingnamespacestd;intmain(){ofstreamoutfile("data.bin",ios::binary);//定义并打开一个输出文件流对象outfile.close();return0;}设想一下这样一种情景:程序在某一文件中写入了一些数据。程序关闭后,这时候操作者发觉少录入了一些数据,需要往文件中再继续写入一些数据。这时候不能用ios::
binary方式打开文件写文件。需要用追加二进制写的方式。7.4.3二进制文件操作
——追加写文件以追加输出和二进制方式打开文件用成员函数write写文件关闭文件一个例子:ofstreamoutfile(“data.bin”,ios::binary|ios::app);intnum1=100;doublenum2=99.01;chartext[20]="helloworld!";outfile.write((char*)&num1,sizeof(int));outfile.write((char*)&num2,sizeof(double));outfile.write((char*)text,sizeof(text));outfile.close();#include<fstream>usingnamespacestd;intmain(){intnum1=100;doublenum2=99.01;chartext[20]="helloworld!";
ofstreamoutfile("data.bin",ios::app|ios::binary);outfile.write((char*)&num1,sizeof(int));outfile.write((char*)&num2,sizeof(double));outfile.write((char*)text,sizeof(text));outfile.close();return0;}//文件输出流对象ofstream在//文件fstream中声明以上程序会在文件data.bin末尾添加数据。原有的数据不会删除。7.4.3二进制文件操作
——读文件以二进制方式打开文件用成员函数read读文件关闭文件一个例子:假设二进制文件中的保存有一个整数100一个双精度数99.01和一个20个元素的字符数组helloworld!ifstreaminfile("data.txt",ios::binary);intnum1;infile.read((char*)&num1,sizeof(int));doublenum2;infile.read((char*)&num2,sizeof(double));chartext[20];infile.read((char*)text,sizeof(text));infile.close();#include<fstream>#include<iostream>usingnamespacestd;intmain(){intnum1;doublenum2;chartext[20];ifstreaminfile("data.bin",ios::binary);infile.read((char*)&num1,sizeof(int));infile.read((char*)&num2,sizeof(double));infile.read((char*)text,sizeof(text));infile.close();cout<<num1<<''<<num2<<''<<text;return0;}以上会输出:10099.01helloworld!7.4.3二进制文件操作
——读文件练习:假设二进制文件“data.bin”中的内容为:三个单精度浮点数的二进制形式,两个数字之间以空格隔开,三个数分别为85,80,95请定义三个变量:英语成绩,数学成绩,语文成绩,将文件中的数据依次读到这三个变量中,显示这三个成绩的值。#include<fstream>//声明流对象ofsteam的头文件#include<iostream>//声明流对象cout和cin的头文件usingnamespacestd;intmain(){floatscoreEng;floatscoreMath;floatscoreChn;ifstreaminfile("data.bin",ios::binary);//定义并打开一个输出文件流对象infile.read((char*)&scoreEng,sizeof(float));infile.read((char*)&scoreMath,sizeof(float));infile.read((char*)&scoreChn,sizeof(float));infile.close();cout<<scoreEng<<''<<scoreMath<<''<<scoreChn<<endl;return0;}7.4.3二进制文件操作
——其它一些细节1:文件打开的两种方式方法一:定义文件流对象的同时指定参数,如:
ifstreaminfile("data.bin",ios::binary);方法二:调用文件流对象的成员函数open,如:ifstreaminfile;infile.open("data.bin",ios::binary);2:检测文件打开是否失败的方法判断方法:若文件打开失败,则文件流对象的类型转换函数返回false,否则返回true。1和2的规则同ASCII文件的操作规则3:以可读可写的方式打开需要用类fstream的对象进行操作,打开方式要写ios::binary|ios::in|ios::out。如:fstreamiofile("data.txt",ios::binary|ios::in|ios::out);7.4.4二进制文件操作
——随机访问文件二进制文件读写的时候用户可以设置读写的位置,在指定位置执行读写操作。什么是随机访问?二进制文件的读写位置如何指定?g:get(输入操作)p:put(输出操作)以字节数计量位置,有以下成员函数提供位置设置与查询功能7.4.4二进制文件操作
——随机访问文件参照位置表示以什么作为移动起点。
ios::beg以文件开始为起点,这是默认值。
ios::cur以指针当前位置为起点。
ios::end
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 2024年度中草药原料供应风险管理合同3篇
- 2024年度客运事故人身损害赔偿合同样本3篇
- 2024版精装公寓短租合同:房屋使用与设施维护协议2篇
- 2024年度大数据分析与咨询服务共享合同3篇
- 2024版CEO聘用合同(包括知识产权归属与保密义务)2篇
- 2024版创新特色美食餐厅经营托管服务合同2篇
- 2024年度西安出租车行业工会组织建设合同3篇
- 2024版砖厂承包与绿色建筑材料研发合同3篇
- 2024年度工地装修材料物流与配送合同3篇
- 2024年度家禽养殖废弃物资源化利用合同3篇
- 血栓弹力图(共28张PPT)精选
- 喜茶营销策略分析
- 别墅小区防盗报警系统设计方案
- DB37∕T 5016-2021 民用建筑外窗工程技术标准
- 操作系统填空题
- 《阿利的红斗篷》阅读题及答案
- [QC]提高隧道防水板一次安装合格率
- 产科重点专科汇报课件
- 金属风管支架重量计算表
- 义务教育《劳动》课程标准(2022年版)
- 300KW并网电站方案
评论
0/150
提交评论