440 likes | 656 Views
第十讲 I/O 流. 流 :数据从一个对象到另一个对象的流动 流是一种抽象,负责在数据的生产者和数据的消费者之间建立联系,并管理数据的流动。. ios. 抽象流基类. istream. 通用输入流类和其他输入流的基类. ifstream. 输入文件流类. istream_withassign. cin 的输入流类. istrstream. 输入字符串流类. ostream. 通用输出流类和其他输出流的基类. ofstream. 输出文件流. ostream_withassign. cout,cerr,clog 的输入流类. ostrstream.
E N D
第十讲 I/O流 流:数据从一个对象到另一个对象的流动 流是一种抽象,负责在数据的生产者和数据的消费者之间建立联系,并管理数据的流动。
ios 抽象流基类 istream 通用输入流类和其他输入流的基类 ifstream 输入文件流类 istream_withassign cin的输入流类 istrstream 输入字符串流类 ostream 通用输出流类和其他输出流的基类 ofstream 输出文件流 ostream_withassign cout,cerr,clog的输入流类 ostrstream 输出字符串流类 iostream 通用输入输出流类和其他输入输出流的基类 fstream 输入输出文件流类 strstream 输入输出字符串流类 stdiostream 标准I/O文件的输入输出类
I/O流类库各个类之间的关系 ios public istream public istrstream public istream_withassign public ifstream iostream public ostream public fstream public public ostrstream strstream public public ostream_withassign stdiostream public ofstream
I/O流类所在包含文件 ios iostream.h istream iostream.h ifstream fstream.h istream_withassign iostream.h istrstream strstrea.h ostream iostream.h ofstream fstream.h ostream_withassign iostream.h ostrstream strstrea.h iostream iostream.h fstream fstream.h strstream strstrea.h stdiostream stdiostr.h
I/O流操作 • 标准流类 • 文件流类 • 串流类 • 控制符 • 重载插入运算符
标准流类 标准头文件:iostream.h 对应标准设备表: cin:键盘 cout:屏幕 cerr:屏幕//错误信息不再重定向,没有缓冲 clog:打印机//类似cerr,有缓冲,缓冲区满输出
标准流对象的定义: cin : istream cin; cout: ostream cout cerr: ostream cerr clog: ostream clog
文件流类 ofstream,ifstream,fstream 文件流类定义的操作应用于外部设备,最典型的设备是磁盘中的文件。 • 文件输出流 • 输出流成员函数 • 文件输入流 • 输入流成员函数
文件输出流 • 构造对象时指定文件名和模式 Ofstream::ofstream(char* pFileName, int mode=ios::out, int prot=filebuf::openprot) pFileName: 文件名 mode:文件打开模式 prot:文件共享方式
使用成员函数打开文件 voidopen(constchar*szName, intnMode=ios::out, intnProt=filebuf::openprot); 在对象消失时,由析构函数关闭由构造函数或open成员函数打开的文件。
文件打开选项 ios::ate 如果文件存在,输出内容加在末尾 ios::in 具有输入能力 ios::out 具有输出能力 ios::trunc 如果文件存在,清除文件内容 ios::nocreate 如果文件不存在,返回错误 ios::noreplace 如果文件存在,返回错误 ios::binary 以二进制方式打开文件(不转换字符) 可以用‘|’组合打开方式 Ios::ate 如果文件存在,输出内容加在末尾
文件保护方式选项 Filebuf::openprot 兼容共享方式 Filebuf::sh_none 独占,不共享 Filebuf::sh_read 允许读共享 Filebuf::sh_write 允许写共享
例: /*向文件myfile中写入一些信息,如果文件不存在,则创建该文件*/ //构造对象时打开文件 ofstream fout("e:\\temp\\myfile.txt"); fout<<"this is"<<endl; //使用成员函数 ofstream fout; fout.open("e:\\temp\\myfile.txt"); fout<<"this is"<<endl;
//向文件myfile中追加一些信息: //构造对象时打开文件 ofstream fadd("e:\\temp\\myfile.txt",ios::ate); fadd<<"a new file"<<endl; //调用成员函数 ofstream fout; fout.open("e:\\temp\\myfile.txt",ios::ate); fout<<" a new file "<<endl;
输出流成员函数 • Put函数输出一个字符 ostream&put(charch); ofstream fout("e:\\temp\\myfile.txt",ios::ate); fout.put(‘A’)<<endl;//宽度和填充方式不起作用 fout<<‘A’<<endl;//宽度和填充方式起作用
例: cout<<setw(10); cout.put('a')<<endl; cout<<setw(10); cout<<'a'<<endl; 输出结果: a _ _ _ _ _ _ _ _ _ a
write函数 内存中的一块内容写到输出文件流中 ostream&write(constchar*pch, intnCount); pch:内存数据起始地址 nCount:字节数 ofstream fout("e:\\temp\\myfile.txt",ios::ate); char a[]={"write"}; fout.write(a,sizeof(a));
如果需要向文件流写整形或实型数据时,要先将他们转换成字符串:如果需要向文件流写整形或实型数据时,要先将他们转换成字符串: #include <stdio.h> …… float f=123.4567; char fstr[20]; sprintf(fstr,”%f”,f);
seekp seekp:设置文件指针 ostream&seekp(streampospos); ostream&seekp(streamoffoff,ios::seek_dirdir); pos:长整形,指针的新位置 off:长整形,指针的偏移量 dir:相对位置: ios::beg文件头 ios::cur文件指针的当前位置 ios::end文件尾
tellp:返回文件指针 streampostellp(); ofstream fout("e:\\temp\\myfile.txt"); fout.seekp(10);//从文件头部向后移动10个字节 fout<<"10"; int pos; pos=fout.tellp(); pos=pos+2; fout.seekp(pos);//从当前位置向后移动2个字节 fout<<"12";
close()函数 关闭文件,当在同一个流对象上打开了另外的文件,调用close()函数。 ofstream fout; fout.open(“file1”); …… fout.close(); fout.open(“file2”); …… fout.close();
错误处理函数 bad:出现不可恢复的错误,返回非0值 fail:出现不可恢复的错误或一个预期条件,返回非0值 good:没有错误,没有文件结束,返回非0值 eof:文件结束,返回非0值 clear:清除所有错误位 rdstate:返回当前错误状态 if(cout.fail()) cerr<<“文件未打开”<<endl;
文件输入流 • 构造对象时打开文件 ifstream( const char* szName, int nMode = ios::in, int nProt = filebuf::openprot );
调用成员函数 void open( const char* szName, int nMode = ios::in, int nProt = filebuf::openprot ); 析构函数关闭由构造函数和成员函数打开的文件。当打开多个文件时可以使用close函数关闭文件。
输入流成员函数 • get函数 输入一个字符 char a[10]; int i=0; ifstream fin("e:\\temp\\myfile.txt"); while(!fin.eof()){ a[i]=fin.get();//输入带空格 //或fin>>a[i];自动过滤空格 i++; }
getline函数 istream& getline( char* pch, int nCount, char delim = '\n' ); 从流中向存储器pch读入多个字符,直到遇到以下情况之一: 所读字符个数将达到nCount; 将遇到终止字符; 文件结束。
read 函数 istream& read( char* pch, int nCount ); //从文件读nCount个字节到指定的存储区 char d[100]; ifstream fin("e:\\temp\\myfile.txt"); fin.read(d,20);
seekg函数 返回下一个将读位置的指针 • tellg函数 设置下一个将读位置的指针 //从流中间隔读入字符 while(!fin.eof()){ pos=fin.tellg(); pos++; fin.seekg(pos); fin.get(d[i]); i++; }
串流类 ostrstream,istrstream,strstream 串流类允许将fstream类定义的文件操作应用于存储区中的字符串。 串流类将字符串看作为设备。 • 串流输入 • 串流输出
串流输入 istrstream( char* pch, int nLength ); char str[10]={"student"}; char a[5]; istrstream ai(str,sizeof(a)-1); ai>>a;
串流输出 ostrstream( char* pch, int nLength, int nMode = ios::out ); pch: 字符串数组 nLength: 数组大小,当字符个数超过nLength 时,字符串不再接受输出 nMode: 打开方式
//向字符数组中写入字符串 char str[10]; ostrstream aout(str,sizeof(str)); aout<<"a student"<<endl;
控制符 • 输出宽度和填充字符 • 进制 • 格式标志值 • 精度
输出宽度和填充字符 setw(int wide) 设置域宽为wide setfill(char ch) 设置填充字符为ch
进制 dec:十进制 oct:八进制 hex:十六进制
格式标志值 使用带参数的setiosflags操纵符可以设置格式,它的影响是持久的,直到用resetiosflags恢复缺省值。
Ios::skipws 在输入中跳过空白 Ios::left 左对齐 Ios::right右对齐 Ios::internal 在指定任何引导标记或基之后增加填充字符 Ios::dec 以十进制格式化数值 Ios::oct 以八进制格式化数值 Ios::hex 以十六进制格式化数值 Ios::showbase 以C++编译器能读的格式显示数值常量
Ios::showpoint 对浮点数值显示小数点和尾部的0 Ios::uppercase 对十六进制数值显示大写字母A~F,对于科学格式显示大写字母E。 Ios::showpos 对于正数显示正号 Ios::scientifil以科学格式显示浮点数值 Ios::fixed 以定点格式显示浮点数值
精度 浮点数输出有效位数的缺省值是6,可以用setprecition改变精度(小数点后位数)。 float a=234.5678923; cout<<setiosflags(ios::fixed) <<setw(10) <<setprecision(5) <<a<<resetiosflags(ios::fixed) <<endl;
重载插入运算符 当向流输出类对象时,需要对插入运算符进行重载。
class base { private: int m; int n; public: base(int i,int j):m(i),n(j){} virtual void view(ostream& out){ out<<"m="<<m<<endl; out<<"n="<<n<<endl; } };
ostream& operator<<(ostream& out,base& b) { b.view(out); return out; } main() { base b(10,20); ofstream fout("e:\\temp\\myfile.txt"); fout<<b<<endl; }
如果该类有一个派生类: class der:public base { public: der(int i,int j):base(i,j){} void view(ostream& out) { out<<"in der"<<endl; base::view(out); } };
执行: base b1(10,20); der d1(100,200); ofstream fout("e:\\temp\\myfile.txt"); fout<<b1<<d1<<endl; 会向文件中写入: m=10 n=20 in der m=100 n=200