220 likes | 411 Views
第八章 输入输出类层次. 流:用于输入输出地一组类 主要内容:文本流、二进制流. ios. cout. ostream. istream. cin. clog. cerr. iostream. iostream.h. ifstream. ofstream. fstream. 流类的继承体系. 输入流和输出流 C ++无专门的输入输出语句,是由流库完成;流与特定的设备相联系。. 输出设备. 文件. 程序. 输入设备. cout.operator<<(“string”);. 输出流
E N D
第八章 输入输出类层次 流:用于输入输出地一组类 主要内容:文本流、二进制流
ios cout ostream istream cin clog cerr iostream iostream.h ifstream ofstream fstream 流类的继承体系 输入流和输出流 C++无专门的输入输出语句,是由流库完成;流与特定的设备相联系。
输出设备 文件 程序 输入设备 cout.operator<<(“string”); 输出流 cout : 输出流ostream类的一个预定义对象 与标准输出设备(终端屏幕)相联系 ostream中重载了<<运算符(插入运算符) 插入运算符<<: ostream& operator<<(类型); //重载形式:注意优先级和结合顺序 cout<<“string”;
11.1.2 输入流 cin>>i; cin.operator>>(i); >>析取运算符:跳过开始空白字符。 char ch; cin>>ch; //输入“ x”,读入‘x’ 注意:C++编译器将根据对象类型选用相应版本的重载<<(>>)运算符函数,用户不必关心。 >>读入一个字符串时,空格作为串的终止。 char buffer[20]; cin>>buffer; //输入“Jack Spart”,读入“Jack” 类型不符,返回零值,并终止程序。 int readints( ) { int v[10]; for(int i=0; i<10;i++) { if(cin>>v[i]) continue; return i; } //…… } 输入:1 2 3 4 5. 6 7 8
第二个参数是要输入输出的对象 第一个参数是流 返回流的引用 11.1.4 重载插入和析取运算符(对用户定义类型) class Complex { double rpart, ipart; public: friend ostream&operator<<(ostream &s, Complex &c); //…… }; #include<iostream.h> class Complex { double rpart, ipart; public: Complex(double r=0.0, double i=0.0) { ipart=i; part=r; } friend ostream&operator>>(ostream &, Complex &); friend ostream&operator<<(ostream &, Complex &); };
istream& operator>>(istream& s, Complex &c) { s>>’(‘>>c.rpart>>’,’>>c.ipart>>’)’; return s; } ostream& operator>>(ostream& s, Complex &c) { s<<’(‘<<c.rpart<<’,’<<c.ipart<<’)’; return s; } void main( ) { Complex c; cin>>c; cout<<“Complex:”<<c<<endl; }
11.2 格式化输入/输出 用ios类中定义的格式成员函数: class ios { //…… public: int width(int w); //设置字段宽度 int width( ) const; //返回设置字段的宽度 char fill(char); //设置填充字符 char fill( ) const; //返回设置的填充字符 long flags(long f); long flags( ) const; long setf(long setbits, long field); long setf(long); long unsetf(long); int precision(int); //设置浮点数精度 int precision( ) const; //返回设置的浮点数精度 //…… };
函数的使用: 输入流: char buffer[20]; cin.width(20); cin>>buffer; 输出流: cout.width(4); cout<<‘(‘<<12<<‘) ’; cout.width(4); cout.fill(‘#’); cout<<‘(‘<<12<<‘) ’; ( 12) ( ##12) Width( )作用于输入/输出的数字或串
(121212) ( ##12) , (12) 数据的长度超过width,忽略设置,按数据实际长度显示; cout.width(4); cout<<‘(‘<<121212<<‘) ’; 每次插入操作后,width被置0; cout.width(4); cout.fill(‘#’); cout<<‘(‘<<12<<“),(“ <<12<<‘) ’;
11.2.2 格式状态 Ios中用枚举记录标志,控制I/O class ios { public: enum{ skipws=01, //析取操作忽略空白字符 left=02, right=04, internal=010, //值按右对齐,符号按左对齐 dec=020, oct=040, hex=0100, showbase=0200, showpoint=0400, //float,double显示小数和尾数后的零 uppercase=01000, showpos=02000, //在正整数前插入“+”号 scientific=04000, //科学计数法,小数点前一位数字 //…… }; //…… };
可用下列函数设置、读取、取消标志位; long flags( )//返回当前格式化标志值 long flags(long f)//设置标志值f,并返回上次标志值 long setf(long f)//设置标志位f,并返回上次标志位 long unsetf(long f)//取消在f中设置的标志位,并返回上次标志位 举例: void your_function( ) { long old_options=cout.flags(ios::left | ios::oct | ios::showpoint); //…… cout.flags(old_options); }
原选项基础上增加showbase cout.setf(ios::showbase); cout.flags(cout.flags( ) | ios::showbase); 相抵触的标志不能同时设置,如:ios::dec和ios::oct 带伪参数的setf( )指明设置哪类选项,自动清除与新设置矛盾的旧选项。 cout<<1234<<‘ ‘<<; cout.setf(ios::oct, ios::basefield); cout<<1234<<‘ ‘<<; cout<<1234<<‘ ‘<<; cout.setf(ios::hex, ios::basefield); cout<<1234<<‘ ‘<<; 伪参数:基数设置位 作用范围:下一标志位设置 结果: 1234 2322 2322 4d2
控制符如endl int x=1, y=2 cout.width(5); cout<<x; cout.width(4); cout<<y; int x=1, y=2; cout<<setw(5)<<x<<setw(4)<<y; 宽度控制符 11.3 控制符 函数控制不方便 预定义控制符有: hex dec oct——指定基数,缺省dec ws——用于输入流,略去空白 endl——换行 ends——插入一个NULL(0)字符,结束一个字符串 flush——强制将流从缓冲区写入相应设备 setfill(char f)——设置填充字符,缺省委空格 setprecision(int p)——设浮点数精度,缺省为6 …..
文件与流建立起联系 11.5.1 打开文件 输入打开文件用ifstream类;输出打开文件用ofstream类; 输入 输出打开文件用fstream类。 11.5 文件和流 处理文件的类在fstream.h中定义。 文件输入输出:1、创建流对象 2、使用流的成员函数打开文件 #include<iostream.h> #lnclude<fstream.h> void main( ) { ofstream my_file; my_file.open(“hello.dat”, ios::out); //…… } 输出流对象my_file与文件hello.dat相联系
打开文件: void open(char* name, int mode, int file_attrb); mode为下列一些方式: ios::app——附加方式写到流 ios::ate——打开文件,并把文件指针移到文件尾 ios::in——为读打开 ios::out——为写打开 ios::trunc——如文件存在,舍去文件内容 ios::nocreate——文件不存在,则失败 ios::noreplace——文件存在,则失败 file_attrb文件属性: 普通文件、只读文件、隐藏文件。
ofstream my_file(“hello.dat”); #include<iostream.h> #lnclude<fstream.h> void main( ) { ofstream my_file; my_file.open(“hello.dat”); my_file<<“Hello world”<<endl; my_file.close( ); }
11.5.2 按正文方式读文件 #lnclude<fstream.h> void main( ) { char string1[20], string2[20]; ifstream my_file(“hello.dat”); my_file>>string1; my_file>>string2; cout<<string1<<‘ ‘<<string2<<endl; my_file.close( ); }
11.5.3 按二进制方式读/写文件 读写的数据无含义,不用<<和>>,而是get( )和put( ) istream & get(char &c); ostream& put(char &c); 写数据: #lnclude<fstream.h> void main( ) { char my_char; static char string[ ]=“Hello world”; int i=0; ofstream my_out_file(“hello.dat”); while(string[i]) my_out_file.put (string[i++] ); my_out_file.close( ); }
读数据: #lnclude<fstream.h> void main( ) { char my_char; int i=0; ifstream my_in_file(“hello.dat”); while(my_in_file) { my_in_file.get(my_char ); cout<<my_char; } my_in_file.close( ); }
11.5.4 使用read( ) 和write( )函数 一次读写多个字符,其原型: istream & read(unsigned char* char_buffer, int number_bytes); ostream& write(const unsigned char* char_buffer , int number_bytes); #lnclude<fstream.h> #include<string.h> void main( ) { static char hello_buf[ ]=“hellow world.\n”; ofstream my_out_file(“hello.dat”); my_out_file.write(hello_buf, sizeof(hello_buff)); ifstream my_in_file(“hello.dat”); my_in_file.read(hello_buf, sizeof(hello_buf)); my_in_file.close( ); my_out_file.close( ); }
11.5.5 使用文件指针 读指针 写指针 用istream中成员函数seekg( )定位;用ostream中成员函数seekp( )定位。 其原型: istream& seekg( streamoff file_offset, seek_dir org); ostream& seekp( streamoff file_offset, seek_dir org); seek_dir三种取值: ios::beg ios::end ios::cur #lnclude<fstream.h> #include<string.h> const int INDEX=15; class Entry{ public: char name[20]; float owes; } my_data[INDEX], my_record; 读写指针在文件中位置 指出指针相对于何处
void main( ) { ifstream my_file1(“file.dat”); my_file1.seekg(9*sizeof(Entry), ios::beg); my_file1.read((char*) &my_record, sizeof(Entry)); my_file1.close( ); ofstream my_file2(“file.dat”); my_record.owes=442.96; my_file2.seekp(9*sizeof(Entry), ios::beg); my_file2.write((char*)& my_record, sizeof(Entry)); my_file2.close( ); }