




版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
第10章流类库和输入输出
本章要点本章要点10.1C++的基本流类体系basic_iosbasic_streambufbasic_istreambasic_ostreambasic_ifstreambasic_iostreambasic_ofstreambasic_fstream指针10.1C++的基本流类体系basic_iosbasicC++的基本流类体系说明(*)basic_streambuf不是basic_ios的派生类,而是一个独立的类,只是basic_ios有一个保护访问限制的指针指向它,其作用是管理一个流的缓冲区。basic_ios类模板提供了对流进行格式化输入输出和错误处理的成员函数。basic_istream类模板提供完成提取(输入)操作的成员函数,basic_ostream类模板提供完成插入(输出)操作的成员函数。basic_iostream类是前两者的聚合,并没有增加成员。*从技术上讲,模板并不能派生。但是这些模板只是预先定义了数据类型(如char或wchar_t等等)的模板实例,所以可以继承。C++的基本流类体系说明(*)basic_streambuf标准输入/输出流对象在C++的流类库中定义了四个全局流对象:cin,cout,cerr和clog。cin标准输入流对象,键盘为其对应的标准设备。cout、cerr和clog都是标准输出流对象,显示器为标准输出设备。标准输入/输出流对象在C++的流类库中定义了四个全局流对象:标准输出流对象的区别对象名是否使用缓冲区是否可以重定向cout是是clog是否cerr否否注:这里的区别与头文件、编译环境和运行环境都有较大影响,具体细节非常复杂。标准输出流对象的区别对象名是否使用缓冲区是否可以重定向coucerr对象的不缓冲特性(*) #include<iostream.h>//传统头文件 intmain() { inti=0,j; cerr<<“SEU”;//更换cout和clog对比 j=5/i; return0; }cerr对象的不缓冲特性(*) #include<iostcout的重定向(*) #include<iostream> usingnamespacestd; intmain() { cout<<"SEU\n"; cerr<<"NJU\n"; clog<<"PKU\n"; return0;}//命令行方式下运行**.exe>>**.txtcout的重定向(*) #include<iostream提取运算符和插入运算符提取运算符“>>”(stream_extractionoperator)和插入运算符“<<”(stream_insertionoperator),执行输入/输出操作。
“提取”的含义是指输入操作,可看作从流中提取一个字符序列。
“插入”的含义是指输出操作,可看作向流中插入一个字符序列。提取运算符和插入运算符提取运算符“>>”(stream_ex重载插入和提取运算符插入和提取运算符只能重载为类的友元函数提取运算符重载格式:friendistream&operator>>(istream&,className&);插入运算符重载格式:friendostream&operator<<(ostream&,className&);流对象作为返回值和参数必须是引用!!!重载插入和提取运算符插入和提取运算符只能重载为类的友元函数插入运算符重载:mystring类重载插入运算符“<<”声明为mystring的友元: friendostream&operator<<(ostream&,constmystring&);
定义为: ostream&operator<<(ostream&s,constmystring&cstr) {returns<<cstr.str<<'\t';}插入运算符重载:mystring类重载插入运算符“<<”声明插入运算符重载:Orderedlist类 template<typename
T,intsize>void<T,size>::print(){inti; for(i=0;i<=last;i++) { cout<<slist[i].key;//这句是关键 if(i%5==4)cout<<endl;} cout<<endl; }插入运算符重载:Orderedlist类 template插入运算符重载:复数类 ostream&operator<<(ostream&s,constComplex&z) {
returns<<'('<<z.Real<<','<<z.Image<<')';}插入运算符重载:复数类 ostream&operator<<提取运算符重载:复数类 istream&operator>>(istream&s,Complex&a){
//格式为d,(d),(d,d)
doublere=0,im=0;charc=0;s>>c;
if(c=='('){//是否由括号开始
s>>re>>c;//实部
if(c==',')s>>im>>c;//虚部
if(c!=')')s.clear(ios::failbit);}
//漏了括号给一个操作失败标志
else{s.putback(c);//无括号,返回一个字符到输入缓冲区
s>>re;}//实数
if(s)a=Complex(re,im);returns;}提取运算符重载:复数类 istream&operator>>提取运算符重载:复数类分析课本上的这个例子,觉得有什么优点和不足?优点:考虑了多种的实际情况,有一定的健壮性缺点:在输入之前没有提示,程序不够友好在实验当中给出自己的修改意见提取运算符重载:复数类分析课本上的这个例子,觉得有什么优点和提高标准输入/输出的稳健性cin为缓冲流。如果输入错了,回车键按下就无法挽回了。只有把数据取完后,才能重来。输入的数据类型必须与要提取的数据类型一致,否则出错。出错只是在流的状态字state中对应位置位,要重来必须重置状态。空格、回车和制表符可以用来分隔数值数据,但无法分隔字符和字符串。特别需要注意在输入字符和字符串之前的操作。提高标准输入/输出的稳健性cin为缓冲流。如果输入错了,回车程序健壮性的示例:输入成绩 intscore; do { cout<<"请输入您的分数:"; cin>>score; }while(score<0||score>100);
猜测:如果输入一个字符a,后果是?程序健壮性的示例:输入成绩提高程序健壮性:掌控流状态
状态字state为整型
enumios_state{goodbit=0x00, //流正常
eofbit=0x01,
//输入流结束或文件结束已无数据可取
failbit=0x02, //最近的I/O操作失败,流可恢复
badbit=0x04, //最近的I/O操作非法,流可恢复
hardfail=0x08//I/O出现致命错误,流不可恢复}提高程序健壮性:掌控流状态 状态字state为整型提高程序健壮性:掌控流状态
读取状态的有关操作如下:inlineintios::rdstate()const{returnstate;}
//读取状态字inlineintios:operator!()const{returnstate&(badbit|failbit);}
//可用操作符!()代替fail()inlineintios::bad(){returnstate&badbit;}
//返回非法操作位提高程序健壮性:掌控流状态 读取状态的有关操作如下:提高程序健壮性:掌控流状态inlinevoidios::clear(int_i){lock();state=_i;unlock();}
//人工设置状态,可用来清状态inlineintios::eof()const{returnstate&eofbit;}
//返回流(文件)结束位inlineintios::fail()const{returnstate&(badbit|failbit);}
//返回操作非法和操作失败这两位inlineintios::good()const{returnstate==0;}
//正常返回1,否则返回0提高程序健壮性:掌控流状态inlinevoidios::程序健壮性的示例:输入成绩 intscore; do { cin.clear(); cout<<"请输入您的分数:"; cin>>score; }while(score<0||score>100);
猜测:这样的改进有用吗?程序健壮性的示例:输入成绩提高程序健壮性:清空缓冲区方法一、用cin.getline()等方式提走缓冲区内容 do { cout<<"请输入您的分数:"; cin>>score; cin.clear(ios::goodbit); cin.getline(s,100);//chars[100]; }while(score<0||score>100);提高程序健壮性:清空缓冲区方法一、用cin.getline(提高程序健壮性:清空缓冲区方法二、使用函数cin.ignore()提取缓冲区内容 do { cout<<"请输入您的分数:"; cin>>score; cin.clear(ios::goodbit); cin.ignore(255,'\n'); }while(score<0||score>100);提高程序健壮性:清空缓冲区方法二、使用函数cin.ignor提高程序健壮性:清空缓冲区方法三、使用函数cin.sync()清空输入缓冲区 do { cout<<"请输入您的分数:"; cin>>score; cin.clear(ios::goodbit); cin.sync(); }while(score<0||score>100);提高程序健壮性:清空缓冲区方法三、使用函数cin.sync(标准输入/输出成员函数intistream::get();istream&istream::get(char&);istream&istream::get(char*,int,char=’\n’);//不提取终止符istream&istream::getline(char*,int,char=’\n’);
//提取终止符并丢弃
提示:如果是超出数量而结束字符串输入,需要重置流状态。标准输入/输出成员函数intistream::get();标准输入/输出成员函数 chars[100]; intnum; cin.getline(s,2,‘#’);//如输入abcd# cout<<s<<endl;
cin.clear(0);cin.sync();//必须写这两句 cin>>num; cout<<num<<endl;标准输入/输出成员函数 chars[100];10.2文件的输入与输出C++根据文件(file)内容的数据格式,可分为两类:二进制文件和文本文件。文本文件由字符序列组成,也称ASCII码文件,在文本文件中存取的最小信息单位为字符(character),而二进制文件中存取的最小信息单位为字节(Byte)。文本文件的读写容易理解,二进制文件读写效率较高。读写文件需包含头文件fstream10.2文件的输入与输出C++根据文件(file)内容的数读写文件四部曲1、定义文件对象,根据读写方式区分 ifstreamifile;//只输入用 ofstreamofile;//只输出用 fstreamiofile;//既输入又输出用
读写文件四部曲1、定义文件对象,根据读写方式区分读写文件四部曲2、使用文件流对象的成员函数打开一个磁盘文件。这样在文件流对象和磁盘文件名之间建立联系。以ifstream类为例: void
ifstream::open(const
char*,int=ios::in,int=);
其中参数一是字符串形式的文件名,参数二是打开方式,参数三一般使用默认值。
注意:如果文件名中包含路径,\符号必须连续使用,如d:\\my.txt 读写文件四部曲2、使用文件流对象的成员函数打开一个磁盘文件。读写文件的打开方式打开方式读/写说明ios::in只读方式文件不存在报错ios::out只写方式文件存在覆盖ios::ate定位到尾部等待后续操作ios::app只写追加方式文件存在继续写ios::trunc覆盖方式ios::binary二进制必须读写文件的打开方式打开方式读/写说明ios::in只读方式文读写文件的四部曲三个文件流类都重载了一个带默认参数的构造函数,功能与open函数一样:ifstream::ifstream(const
char*,int=ios::in,
int=);ofstream::ofstream(const
char*,int=ios::out,
int=);fstream::fstream(constchar*,int,
int=);读写文件的四部曲三个文件流类都重载了一个带默认参数的构造函数读写文件的四部曲打开文件也应该判断是否成功,若成功,文件流对象值为非零值,不成功为0(NULL)。因此打开一个文件完整的程序为: fstreamiofile(”my”,ios::in|ios::out); if(!iofile){//“!”为重载的运算符,见9.3.1节 cout<<”不能打开文件:”<<”my”<<endl; return-1;
}//失败退回读写文件的四部曲打开文件也应该判断是否成功,若成功,文件流对文本文件的读写如果将键盘和显示器看成特殊的文件,那么我们熟练的输入输出和文件读写就可以统一概念了。输入和读文件本质上是一致的;输出和写文件本质上是一致的。因此之前熟悉的运算符和函数都几乎可以直接用于文本文件的读写。文本文件的读写如果将键盘和显示器看成特殊的文件,那么我们熟练文本读写——按字符复制文件
intmain(){
charch;ifstreamsfile("d:\\1.txt"); ofstreamdfile("d:\\2.txt"); if(!sfile){cout<<"不能打开源文件:"<<endl; return-1;}文本读写——按字符复制文件 intmain(){文本读写——按字符复制文件 if(!dfile){ cout<<"不能打开目标文件:"<<endl;
return-1;}s(ios::skipws);
//关键!把跳过空白控制位置0,即不跳过空白格
while(sfile>>ch)dfile<<ch;s();//如没有这两个关闭函数,析构函数也可关闭
d();return0;}文本读写——按字符复制文件 if(!dfile){文本读写——按字符复制文件1、使用默认的>>获取字符时,会跳过空白符号。除了选择关闭设置之外,可以用s(ch)来代替即可。2、当读到文件尾部之后,流对象sfile进入eof状态,在循环判断中会被判断为NULL,因此循环停止。3、本算法可以复制所有文件,但效率较低。文本读写——按字符复制文件1、使用默认的>>获取字符时,会跳文本读写——按行复制文件chars[2];//极端测试
do {
i(s,2); if(i()==0) ofile<<s<<endl; elseif(i()==4){ i();ofile<<s; } else{ ofile<<s; break;} }while(1);文本读写——按行复制文件chars[2];//极端测试 文本读写——按行复制文件1、通过默认符号\n终止读取的,则流状态正常,但因为getline不提取回车符,在复制时需要手工补上。2、通过字符上限终止读取的,流状态变成fail,需要将其置为正常才能继续。3、该算法效率较高,但不适合二进制文件,因为二进制文件根本没有行。文本读写——按行复制文件1、通过默认符号\n终止读取的,则流文本文件读写总结基本上,文本文件的读写和输入输出的使用是很相近的,大部分函数和符号可以直接通用。提取和插入运算符的重载也可以用于文件对象,用于将类的内容从文件输入或写入文件。读文件的时候,需要注意判断文件流的状态。文本文件读写总结基本上,文本文件的读写和输入输出的使用是很相文本文件读写和运算符
classMoney {
intyuan,jiao,fen;
public: Money(inty=0,intj=0,intf=0) {yuan=y;jiao=j;fen=f;}
friendistream&operator>>(istream&is,Money&m);
friendostream&operator<<(ostream&os,Money&m); };文本文件读写和运算符 classMoney文本文件读写和运算符istream&operator>>(istream&is,Money&m) { is>>m.yuan>>m.jiao>>m.fen; returnis; }ostream&operator<<(ostream&os,Money&m) { os<<m.yuan<<‘\t’<<m.jiao<<‘\t’<<m.fen;//输出的时候要分割 returnos; }文本文件读写和运算符istream&operator>>(文本文件读写和运算符 intmain(){ Moneym1;cin>>m1;cout<<m1<<endl;//重载输入输出 ofstreamofile("my.txt",ios::out); ofile<<m1;o();//输出到文件 ifstreamifile("my.txt",ios::out); ifile>>m1;i();//从文件读入数据 cout<<m1;}文本文件读写和运算符 intmain(){文本文件读写和运算符重载 istream&operator>>(istream&is,Money&m) { if(&is==&cin)//如果是默认的cin对象 cout<<"请依次输入元、角和分的值,用空格分割,回车符确认:"; is>>m.yuan>>m.jiao>>m.fen; returnis; }文本文件读写和运算符重载 istream&operator二进制文件读写istream&istream::read(char*,int); //从二进制流提取个若干个字节,送入第一个参数地址开始的单元ostream&ostream::write(const
char*,int);//从第一个参数地址读取若干个字节,写入文件流当中二进制文件读写istream&istream::read(c二进制文件读写 voidWriteTo&ofile); voidReadFrom&ifile); voidshow()//原始的show函数 { cout<<yuan<<'\t'<<jiao<<'\t'<<fen<<endl; }二进制文件读写 voidWriteTo&ofile);二进制文件读写 voidMoney::WriteTo&ofile) { o((char*)&yuan,sizeof(yuan)); o((char*)&jiao,sizeof(jiao)); o((char*)&fen,sizeof(fen)); o(); }二进制文件读写 voidMoney::WriteTo&o二进制文件读写 voidMoney::ReadFrom&ifile) { i((char*)&yuan,sizeof(yuan)); i((char*)&jiao,sizeof(jiao)); i((char*)&fen,sizeof(fen)); i(); }二进制文件读写二进制文件读写 intmain() {Moneym1(1,2,3),m2; ofstreamofile("my.dat",ios::binary); ifstreamifile("my.dat",ios::binary); m1.WriteTo); m2.ReadFrom); m2.show(); return0;}二进制文件读写 intmain()二进制文件和文本文件读写二进制文件可以控制字节长度,读写数据时不会出现二义性,可靠性高。对于复杂数据,如数组、结构体、对象等,读写方便。二进制文件保密性好,必须知道写文件的过程才能知道如何读取。二进制文件体积也较小,因此在实际过程中往往首选二进制文件。二进制文件和文本文件读写二进制文件可以控制字节长度,读写数据读文件时的顺序问题 ofstreamofile("d:\\1.dat",ios::binary); inti; for(i=1;i<=10;i++) o((char*)&i,sizeof(i)); o();读文件时的顺序问题 ofstreamofile("d:\\读文件时的顺序问题 ifstreamifile("d:\\1.dat",ios::binary); intx; while(ifile)//或者while(i()==0) { i((char*)&x,sizeof(x)); cout<<x<<endl; } i();//这个代码的结果是??读文件时的顺序问题 ifstreamifile("d:\\读文件时的顺序问题上述代码会多读出一个10出来!正确写法之一: while(i((char*)&x,sizeof(x))) cout<<x<<endl;正确写法之二: do{ i((char*)&x,sizeof(x)); if(!i; cout<<x<<endl; }while(1);读文件时的顺序问题上述代码会多读出一个10出来!读文件的顺序问题当读到文件尾部的时候,数据应该是结束了。但此时eof并不为真,除非再做一次读操作才会。第一个错误代码当中,多做了一次循环,在循环中没有读到任何内容,x保留上一次的值,因此10重复出现了。合理的方案是:先做读操作,马上紧跟判断。读文件的顺序问题当读到文件尾部的时候,数据应该是结束了。但此文件的随机读写(*)之前对文件的读写,都是从文件头顺序操作到文件尾,但有时我们需要灵活的对读写位置定位。读写位置的定位通过两组共6个函数完成。istream&istream::seekg(streampos); istream&istream::seekg(streamoff,ios::seek_dir); longistream::tellg();
对于ostream中的函数只需要将g改p即可。
文件的随机读写(*)之前对文件的读写,都是从文件头顺序操作到指针相对定位ios::seek_dir枚举参数意义注明ios::cur当前位置可用tell获取ios::beg文件起点位移只能为正ios::end文件中点位移只能为负指针相对定位ios::seek_dir枚举参数意义注明ios例:获得任一文件的大小 ifstreamifile("d:\\1.dat",ios::binary); i(0,ios::end);//定位到最后 cout<<i();//读出位置的偏移值例:获得任一文件的大小 ifstreamifile("d:例:数组的随机读写 //文件读写一般对二进制文件适合 ofstreamofile("d:\\1.dat",ios::binary); inta[10]={1,2,3,4,5,6,7,8,9,10},i,x; o((char*)a,sizeof(a)); o();例:数组的随机读写 //文件读写一般对二进制文件适合例:数组的随机读写 //只读取偶数下标的数据,即1,3,5,7,9 ifstreamifile("d:\\1.dat",ios::binary); for(i=0;i<5;i++) {i(i*2*sizeof(a[0]),ios::beg); i((char*)&x,sizeof(x)); cout<<x<<endl;} i();例:数组的随机读写 //只读取偶数下标的数据,即1,3,5,写在最后成功的基础在于好的学习习惯Thefoundationofsuccessliesingoodhabits59写在最后成功的基础在于好的学习习惯59结束语当你尽了自己的最大努力时,失败也是伟大的,所以不要放弃,坚持就是正确的。WhenYouDoYourBest,FailureIsGreat,SoDon'TGiveUp,StickToTheEnd演讲人:XXXXXX时间:XX年XX月XX日
结束语60第10章流类库和输入输出
本章要点本章要点10.1C++的基本流类体系basic_iosbasic_streambufbasic_istreambasic_ostreambasic_ifstreambasic_iostreambasic_ofstreambasic_fstream指针10.1C++的基本流类体系basic_iosbasicC++的基本流类体系说明(*)basic_streambuf不是basic_ios的派生类,而是一个独立的类,只是basic_ios有一个保护访问限制的指针指向它,其作用是管理一个流的缓冲区。basic_ios类模板提供了对流进行格式化输入输出和错误处理的成员函数。basic_istream类模板提供完成提取(输入)操作的成员函数,basic_ostream类模板提供完成插入(输出)操作的成员函数。basic_iostream类是前两者的聚合,并没有增加成员。*从技术上讲,模板并不能派生。但是这些模板只是预先定义了数据类型(如char或wchar_t等等)的模板实例,所以可以继承。C++的基本流类体系说明(*)basic_streambuf标准输入/输出流对象在C++的流类库中定义了四个全局流对象:cin,cout,cerr和clog。cin标准输入流对象,键盘为其对应的标准设备。cout、cerr和clog都是标准输出流对象,显示器为标准输出设备。标准输入/输出流对象在C++的流类库中定义了四个全局流对象:标准输出流对象的区别对象名是否使用缓冲区是否可以重定向cout是是clog是否cerr否否注:这里的区别与头文件、编译环境和运行环境都有较大影响,具体细节非常复杂。标准输出流对象的区别对象名是否使用缓冲区是否可以重定向coucerr对象的不缓冲特性(*) #include<iostream.h>//传统头文件 intmain() { inti=0,j; cerr<<“SEU”;//更换cout和clog对比 j=5/i; return0; }cerr对象的不缓冲特性(*) #include<iostcout的重定向(*) #include<iostream> usingnamespacestd; intmain() { cout<<"SEU\n"; cerr<<"NJU\n"; clog<<"PKU\n"; return0;}//命令行方式下运行**.exe>>**.txtcout的重定向(*) #include<iostream提取运算符和插入运算符提取运算符“>>”(stream_extractionoperator)和插入运算符“<<”(stream_insertionoperator),执行输入/输出操作。
“提取”的含义是指输入操作,可看作从流中提取一个字符序列。
“插入”的含义是指输出操作,可看作向流中插入一个字符序列。提取运算符和插入运算符提取运算符“>>”(stream_ex重载插入和提取运算符插入和提取运算符只能重载为类的友元函数提取运算符重载格式:friendistream&operator>>(istream&,className&);插入运算符重载格式:friendostream&operator<<(ostream&,className&);流对象作为返回值和参数必须是引用!!!重载插入和提取运算符插入和提取运算符只能重载为类的友元函数插入运算符重载:mystring类重载插入运算符“<<”声明为mystring的友元: friendostream&operator<<(ostream&,constmystring&);
定义为: ostream&operator<<(ostream&s,constmystring&cstr) {returns<<cstr.str<<'\t';}插入运算符重载:mystring类重载插入运算符“<<”声明插入运算符重载:Orderedlist类 template<typename
T,intsize>void<T,size>::print(){inti; for(i=0;i<=last;i++) { cout<<slist[i].key;//这句是关键 if(i%5==4)cout<<endl;} cout<<endl; }插入运算符重载:Orderedlist类 template插入运算符重载:复数类 ostream&operator<<(ostream&s,constComplex&z) {
returns<<'('<<z.Real<<','<<z.Image<<')';}插入运算符重载:复数类 ostream&operator<<提取运算符重载:复数类 istream&operator>>(istream&s,Complex&a){
//格式为d,(d),(d,d)
doublere=0,im=0;charc=0;s>>c;
if(c=='('){//是否由括号开始
s>>re>>c;//实部
if(c==',')s>>im>>c;//虚部
if(c!=')')s.clear(ios::failbit);}
//漏了括号给一个操作失败标志
else{s.putback(c);//无括号,返回一个字符到输入缓冲区
s>>re;}//实数
if(s)a=Complex(re,im);returns;}提取运算符重载:复数类 istream&operator>>提取运算符重载:复数类分析课本上的这个例子,觉得有什么优点和不足?优点:考虑了多种的实际情况,有一定的健壮性缺点:在输入之前没有提示,程序不够友好在实验当中给出自己的修改意见提取运算符重载:复数类分析课本上的这个例子,觉得有什么优点和提高标准输入/输出的稳健性cin为缓冲流。如果输入错了,回车键按下就无法挽回了。只有把数据取完后,才能重来。输入的数据类型必须与要提取的数据类型一致,否则出错。出错只是在流的状态字state中对应位置位,要重来必须重置状态。空格、回车和制表符可以用来分隔数值数据,但无法分隔字符和字符串。特别需要注意在输入字符和字符串之前的操作。提高标准输入/输出的稳健性cin为缓冲流。如果输入错了,回车程序健壮性的示例:输入成绩 intscore; do { cout<<"请输入您的分数:"; cin>>score; }while(score<0||score>100);
猜测:如果输入一个字符a,后果是?程序健壮性的示例:输入成绩提高程序健壮性:掌控流状态
状态字state为整型
enumios_state{goodbit=0x00, //流正常
eofbit=0x01,
//输入流结束或文件结束已无数据可取
failbit=0x02, //最近的I/O操作失败,流可恢复
badbit=0x04, //最近的I/O操作非法,流可恢复
hardfail=0x08//I/O出现致命错误,流不可恢复}提高程序健壮性:掌控流状态 状态字state为整型提高程序健壮性:掌控流状态
读取状态的有关操作如下:inlineintios::rdstate()const{returnstate;}
//读取状态字inlineintios:operator!()const{returnstate&(badbit|failbit);}
//可用操作符!()代替fail()inlineintios::bad(){returnstate&badbit;}
//返回非法操作位提高程序健壮性:掌控流状态 读取状态的有关操作如下:提高程序健壮性:掌控流状态inlinevoidios::clear(int_i){lock();state=_i;unlock();}
//人工设置状态,可用来清状态inlineintios::eof()const{returnstate&eofbit;}
//返回流(文件)结束位inlineintios::fail()const{returnstate&(badbit|failbit);}
//返回操作非法和操作失败这两位inlineintios::good()const{returnstate==0;}
//正常返回1,否则返回0提高程序健壮性:掌控流状态inlinevoidios::程序健壮性的示例:输入成绩 intscore; do { cin.clear(); cout<<"请输入您的分数:"; cin>>score; }while(score<0||score>100);
猜测:这样的改进有用吗?程序健壮性的示例:输入成绩提高程序健壮性:清空缓冲区方法一、用cin.getline()等方式提走缓冲区内容 do { cout<<"请输入您的分数:"; cin>>score; cin.clear(ios::goodbit); cin.getline(s,100);//chars[100]; }while(score<0||score>100);提高程序健壮性:清空缓冲区方法一、用cin.getline(提高程序健壮性:清空缓冲区方法二、使用函数cin.ignore()提取缓冲区内容 do { cout<<"请输入您的分数:"; cin>>score; cin.clear(ios::goodbit); cin.ignore(255,'\n'); }while(score<0||score>100);提高程序健壮性:清空缓冲区方法二、使用函数cin.ignor提高程序健壮性:清空缓冲区方法三、使用函数cin.sync()清空输入缓冲区 do { cout<<"请输入您的分数:"; cin>>score; cin.clear(ios::goodbit); cin.sync(); }while(score<0||score>100);提高程序健壮性:清空缓冲区方法三、使用函数cin.sync(标准输入/输出成员函数intistream::get();istream&istream::get(char&);istream&istream::get(char*,int,char=’\n’);//不提取终止符istream&istream::getline(char*,int,char=’\n’);
//提取终止符并丢弃
提示:如果是超出数量而结束字符串输入,需要重置流状态。标准输入/输出成员函数intistream::get();标准输入/输出成员函数 chars[100]; intnum; cin.getline(s,2,‘#’);//如输入abcd# cout<<s<<endl;
cin.clear(0);cin.sync();//必须写这两句 cin>>num; cout<<num<<endl;标准输入/输出成员函数 chars[100];10.2文件的输入与输出C++根据文件(file)内容的数据格式,可分为两类:二进制文件和文本文件。文本文件由字符序列组成,也称ASCII码文件,在文本文件中存取的最小信息单位为字符(character),而二进制文件中存取的最小信息单位为字节(Byte)。文本文件的读写容易理解,二进制文件读写效率较高。读写文件需包含头文件fstream10.2文件的输入与输出C++根据文件(file)内容的数读写文件四部曲1、定义文件对象,根据读写方式区分 ifstreamifile;//只输入用 ofstreamofile;//只输出用 fstreamiofile;//既输入又输出用
读写文件四部曲1、定义文件对象,根据读写方式区分读写文件四部曲2、使用文件流对象的成员函数打开一个磁盘文件。这样在文件流对象和磁盘文件名之间建立联系。以ifstream类为例: void
ifstream::open(const
char*,int=ios::in,int=);
其中参数一是字符串形式的文件名,参数二是打开方式,参数三一般使用默认值。
注意:如果文件名中包含路径,\符号必须连续使用,如d:\\my.txt 读写文件四部曲2、使用文件流对象的成员函数打开一个磁盘文件。读写文件的打开方式打开方式读/写说明ios::in只读方式文件不存在报错ios::out只写方式文件存在覆盖ios::ate定位到尾部等待后续操作ios::app只写追加方式文件存在继续写ios::trunc覆盖方式ios::binary二进制必须读写文件的打开方式打开方式读/写说明ios::in只读方式文读写文件的四部曲三个文件流类都重载了一个带默认参数的构造函数,功能与open函数一样:ifstream::ifstream(const
char*,int=ios::in,
int=);ofstream::ofstream(const
char*,int=ios::out,
int=);fstream::fstream(constchar*,int,
int=);读写文件的四部曲三个文件流类都重载了一个带默认参数的构造函数读写文件的四部曲打开文件也应该判断是否成功,若成功,文件流对象值为非零值,不成功为0(NULL)。因此打开一个文件完整的程序为: fstreamiofile(”my”,ios::in|ios::out); if(!iofile){//“!”为重载的运算符,见9.3.1节 cout<<”不能打开文件:”<<”my”<<endl; return-1;
}//失败退回读写文件的四部曲打开文件也应该判断是否成功,若成功,文件流对文本文件的读写如果将键盘和显示器看成特殊的文件,那么我们熟练的输入输出和文件读写就可以统一概念了。输入和读文件本质上是一致的;输出和写文件本质上是一致的。因此之前熟悉的运算符和函数都几乎可以直接用于文本文件的读写。文本文件的读写如果将键盘和显示器看成特殊的文件,那么我们熟练文本读写——按字符复制文件
intmain(){
charch;ifstreamsfile("d:\\1.txt"); ofstreamdfile("d:\\2.txt"); if(!sfile){cout<<"不能打开源文件:"<<endl; return-1;}文本读写——按字符复制文件 intmain(){文本读写——按字符复制文件 if(!dfile){ cout<<"不能打开目标文件:"<<endl;
return-1;}s(ios::skipws);
//关键!把跳过空白控制位置0,即不跳过空白格
while(sfile>>ch)dfile<<ch;s();//如没有这两个关闭函数,析构函数也可关闭
d();return0;}文本读写——按字符复制文件 if(!dfile){文本读写——按字符复制文件1、使用默认的>>获取字符时,会跳过空白符号。除了选择关闭设置之外,可以用s(ch)来代替即可。2、当读到文件尾部之后,流对象sfile进入eof状态,在循环判断中会被判断为NULL,因此循环停止。3、本算法可以复制所有文件,但效率较低。文本读写——按字符复制文件1、使用默认的>>获取字符时,会跳文本读写——按行复制文件chars[2];//极端测试
do {
i(s,2); if(i()==0) ofile<<s<<endl; elseif(i()==4){ i();ofile<<s; } else{ ofile<<s; break;} }while(1);文本读写——按行复制文件chars[2];//极端测试 文本读写——按行复制文件1、通过默认符号\n终止读取的,则流状态正常,但因为getline不提取回车符,在复制时需要手工补上。2、通过字符上限终止读取的,流状态变成fail,需要将其置为正常才能继续。3、该算法效率较高,但不适合二进制文件,因为二进制文件根本没有行。文本读写——按行复制文件1、通过默认符号\n终止读取的,则流文本文件读写总结基本上,文本文件的读写和输入输出的使用是很相近的,大部分函数和符号可以直接通用。提取和插入运算符的重载也可以用于文件对象,用于将类的内容从文件输入或写入文件。读文件的时候,需要注意判断文件流的状态。文本文件读写总结基本上,文本文件的读写和输入输出的使用是很相文本文件读写和运算符
classMoney {
intyuan,jiao,fen;
public: Money(inty=0,intj=0,intf=0) {yuan=y;jiao=j;fen=f;}
friendistream&operator>>(istream&is,Money&m);
friendostream&operator<<(ostream&os,Money&m); };文本文件读写和运算符 classMoney文本文件读写和运算符istream&operator>>(istream&is,Money&m) { is>>m.yuan>>m.jiao>>m.fen; returnis; }ostream&operator<<(ostream&os,Money&m) { os<<m.yuan<<‘\t’<<m.jiao<<‘\t’<<m.fen;//输出的时候要分割 returnos; }文本文件读写和运算符istream&operator>>(文本文件读写和运算符 intmain(){ Moneym1;cin>>m1;cout<<m1<<endl;//重载输入输出 ofstreamofile("my.txt",ios::out); ofile<<m1;o();//输出到文件 ifstreamifile("my.txt",ios::out); ifile>>m1;i();//从文件读入数据 cout<<m1;}文本文件读写和运算符 intmain(){文本文件读写和运算符重载 istream&operator>>(istream&is,Money&m) { if(&is==&cin)//如果是默认的cin对象 cout<<"请依次输入元、角和分的值,用空格分割,回车符确认:"; is>>m.yuan>>m.jiao>>m.fen; returnis; }文本文件读写和运算符重载 istream&operator二进制文件读写istream&istream::read(char*,int); //从二进制流提取个若干个字节,送入第一个参数地址开始的单元ostream&ostream::write(const
char*,int);//从第一个参数地址读取若干个字节,写入文件流当中二进制文件读写istream&istream::read(c二进制文件读写 voidWriteTo&ofile); voidReadFrom&ifile); voidshow()//原始的show函数 { cout<<yuan<<'\t'<<jiao<<'\t'<<fen<<endl; }二进制文件读写 voidWriteTo&ofile);二进制文件读写 voidMoney::WriteTo&ofile) { o((char*)&yuan,sizeof(yuan)); o((char*)&jiao,sizeof(jiao)); o((char*)&fen,sizeof(fen)); o(); }二进制文件读写 voidMoney::WriteTo&o二进制文件读写 voidMoney::
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 一嗨租车保险合同二零二五年
- 二零二五版租用学校场地协议书范例参考
- 餐饮营运值班管理制度
- 课程管理制度评审标准
- 集团之间资金管理制度
- 辣条公司车间管理制度
- 公司装卸组管理制度
- 食品配餐午餐管理制度
- 高中教室管理制度细则
- 销售门店人员管理制度
- 2025年中国邮政宁夏地区社会招聘90人管理单位笔试遴选500模拟题附带答案详解
- 重症患者的疼痛管理
- 投标人对本项目的合理化建议和改进措施
- 右半结肠癌手术中国专家共识(2024版)
- 二年级下册语文《写字表》生字组词
- 手术室的器械护士
- 劳动用工风险与规范培训
- 咯血病人的护理
- 《公路建设项目文件管理规程》
- 2023年北京按摩医院招聘笔试真题
- 2024年山东省烟台市初中学业水平考试地理试卷含答案
评论
0/150
提交评论