22
第第第 第第第第第第第 第第第 第第第第第第第 第第第第第第第第 第第 :一 第第第第 第第第第 第第第第 :、

第八章 输入输出类层次

Embed Size (px)

DESCRIPTION

第八章 输入输出类层次. 流:用于输入输出地一组类 主要内容:文本流、二进制流. ios. cout. ostream. istream. cin. clog. cerr. iostream. iostream.h. ifstream. ofstream. fstream. 流类的继承体系. 输入流和输出流 C ++无专门的输入输出语句,是由流库完成;流与特定的设备相联系。. 输出设备. 文件. 程序. 输入设备. cout.operator

Citation preview

Page 1: 第八章    输入输出类层次

第八章 输入输出类层次第八章 输入输出类层次

流:用于输入输出地一组类主要内容:文本流、二进制流

Page 2: 第八章    输入输出类层次

输入流和输出流C ++无专门的输入输出语句,是由流库完成;流与特定的设备相联系。

iostream.h

流类的继承体系

ios

ostream istreamclog

fstream

iostream

cerr

cin

ofstream ifstream

cout

Page 3: 第八章    输入输出类层次

输出流 cout : 输出流 ostream 类的一个预定义对象

与标准输出设备(终端屏幕)相联系

ostream 中重载了 << 运算符(插入运算符)

插入运算符 <<: ostream& operator<<( 类型 );

// 重载形式:注意优先级和结合顺序

程序

输入设备

输出设备

文件

cout<<“string”; cout.operator<<(“string”);

Page 4: 第八章    输入输出类层次

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

Page 5: 第八章    输入输出类层次

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 &); };

Page 6: 第八章    输入输出类层次

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; }

Page 7: 第八章    输入输出类层次

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; // 返回设置的浮点数精度 //…… };

Page 8: 第八章    输入输出类层次

函数的使用:

输入流: char buffer[20];

cin.width(20);

cin>>buffer;

输出流: cout.width(4);

cout<<‘(‘<<12<<‘) ’;

cout.width(4);

cout.fill(‘#’);

cout<<‘(‘<<12<<‘) ’;

( 12)

( ##12)

Width( ) 作用于输入 / 输出的数字或串

Page 9: 第八章    输入输出类层次

数据的长度超过 width ,忽略设置,按数据实际长度显示; cout.width(4); cout<<‘(‘<<121212<<‘) ’;每次插入操作后, width 被置 0 ; cout.width(4); cout.fill(‘#’); cout<<‘(‘<<12<<“),(“ <<12<<‘) ’;

(121212)

( ##12) , (12)

Page 10: 第八章    输入输出类层次

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, // 科学计数法,小数点前一位数字

//…… }; //…… };

Page 11: 第八章    输入输出类层次

可用下列函数设置、读取、取消标志位; 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);

}

Page 12: 第八章    输入输出类层次

相抵触的标志不能同时设置,如: 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<<‘ ‘<<;

原选项基础上增加 showbase

伪参数:基数设置位

作用范围:下一标志位设置

cout.flags(cout.flags( ) | ios::showbase);

cout.setf(ios::showbase);

结果: 1234 2322 2322 4d2

Page 13: 第八章    输入输出类层次

11.3 控制符函数控制不方便

int x=1, y=2cout.width(5);cout<<x;cout.width(4);cout<<y;

宽度控制符

预定义控制符有: hex dec oct—— 指定基数,缺省 dec ws—— 用于输入流,略去空白 endl—— 换行 ends—— 插入一个 NULL(0) 字符,结束一个字符串 flush—— 强制将流从缓冲区写入相应设备 setfill(char f)—— 设置填充字符,缺省委空格 setprecision(int p)—— 设浮点数精度,缺省为 6 …..

int x=1, y=2;

cout<<setw(5)<<x<<setw(4)<<y;

控制符如 endl

Page 14: 第八章    输入输出类层次

11.5 文件和流处理文件的类在 fstream.h 中定义。文件输入输出: 1 、创建流对象 2 、使用流的成员函数打开文件 文件与流建立起联系

输出流对象 my_file 与文件 hello.dat 相联系

#include<iostream.h> #lnclude<fstream.h> void main( ) { ofstream my_file; my_file.open(“hello.dat”, ios::out); //…… }

11.5.1 打开文件输入打开文件用 ifstream 类;输出打开文件用 ofstream 类;

输入 输出打开文件用 fstream 类。

Page 15: 第八章    输入输出类层次

打开文件: 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 文件属性 : 普通文件、只读文件、隐藏文件。

Page 16: 第八章    输入输出类层次

#include<iostream.h> #lnclude<fstream.h> void main( ) { ofstream my_file; my_file.open(“hello.dat”); my_file<<“Hello world”<<endl; my_file.close( ); }

ofstream my_file(“hello.dat”);

Page 17: 第八章    输入输出类层次

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( ); }

Page 18: 第八章    输入输出类层次

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( ); }

Page 19: 第八章    输入输出类层次

读数据: #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( ); }

Page 20: 第八章    输入输出类层次

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( );

}

Page 21: 第八章    输入输出类层次

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;

读写指针在文件中位置 指出指针相对于何处

Page 22: 第八章    输入输出类层次

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( ); }