第10章 输入输出流_第1页
第10章 输入输出流_第2页
第10章 输入输出流_第3页
第10章 输入输出流_第4页
第10章 输入输出流_第5页
已阅读5页,还剩47页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

1、第10章 输入输出流内蒙古科技大学信息学院10.1 I/O流的概念及流类库结构流的概念及流类库结构10.2 I /O标准流标准流10.3 插入和提取运算符的重载插入和提取运算符的重载10.4 文件的输入输出文件的输入输出10.5 字符串流操作字符串流操作10.6 本章知识点小结本章知识点小结210.1 I/O流的概念及流类库结构流的概念及流类库结构 在C+语言中,输入是指数据从输入文件传送到程序的过程,输出是指数据从程序传送到输出文件的过程。 C+的输入输出主要包含以下三个方面内容: (1) 标准I/O :对标准输入设备和标准输出设备的输入输出。 (2) 文件I/O:对外存磁盘上文件的输入输出

2、。 (3) 串I/O:对内存中指定的字符串存储空间的输入输出。310.1.1 I/O流的概念流的概念所谓流,这是一个形象的称谓,它是指数据在传送过程中,数据如流水一般从一对象流向另一对象。也就是信息从外部输入设备(如键盘和磁盘)向计算机内部(即内存)输入和从内部向外部输出设备(如显示器和磁盘)输出的过程。C定义的I/O类库中每一个类都可称作流或流类,一个流类所定义的对象也时常称为流。流具有方向性,与输入设备(键盘)相联系的流就称为输入流,与输出设备(显示器)相联系的流就称为输出流,与输入输出设备(硬盘)相联系的流就称为输入输出流。410.1.2 I/O流类库结构流类库结构图图 10-1 ios

3、 类派生层次类派生层次根基类根基类输入流类输入流类输出流类输出流类输入字符串流类输入字符串流类输出字符串流类输出字符串流类输入输出流类输入输出流类文件流基类文件流基类字符串流基类字符串流基类输入输出文件流类输入输出文件流类输入文件流类输入文件流类输出文件流类输出文件流类输入输出输入输出字符串字符串流流类类5C+系统中的I/O类库,其所有类被包含在iostream.h,fstream.h和strstrea.h中。这三个系统头文件中,各头文件包含的类如下:(1) iostream.h包含有:ios, iostream, istream, ostream, iostream_withassign,

4、istream_withassign, ostream_withassign等。(2) fstream.h包含有:fstream, ifstream, ofstream和fstreambase,以及iostream.h中的所有类。(3) strstream.h包含有:strstream, istrstream, ostrstream和strstreambase,以及iostream.h中的所有类。610.2 I /O标准流标准流10.2.1 标准流对象标准流对象C+提供了4个预定义的标准流对象,cout 、cerr 、clog和 cin ,其中:cin 是 istream 类的对象,用来处理标

5、准输入,即程序运行起来后从键盘输入;cout 是 ostream 类的对象,用来处理标准输出,即把程序运行的结果输出到显示器上;cerr 和 clog 都是 ostream 类的对象,用来处理标准出错信息,并将信息显示在显示器上。在这4个标准流对象中,除了 cerr 不支持缓冲外,其余3个都带有缓冲区。710.2.2 标准输出流标准输出流ostream类定义了3个输出流对象,即cout,cerr,clog。分述如下:1cout,cerr,clog (1) cout流对象cout是console output的缩写,意为在控制台(终端显示器)的输出。cout不是C+预定义的关键字,它是ostre

6、am流类的对象,cout流中的数据是用流插入,cout流是容纳数据的载体,它并不是一个运算符。用“cout”输出基本类型的数据时,可以不必考虑数据是什么类型,系统会判断。 也可以自己构造输出流对象。例如:ostream obj; 8(2) cerr流对象cerr是console error的缩写,意为“在控制台(显示器)显示出错信息”,cerr流对象是标准错误流。cerr的作用是向标准错误设备(standard error device)输出有关出错信息。cerr不能被缓冲,cerr流已被指定为与显示器关联,它的输出总是直接传达到标准输出设备上,是不能重定向的。错误信息是写到cerr的项。例如

7、:cerr “Error” “n”; 使用该语句,则错误信息“Error”总能保证在显示器上显示出来。9(3) clog流对象它是console log的缩写,clog流对象也是标准错误流。它的作用和cout相同,都是在终端显示器上显示出错信息。clog是不能重定向的,但是可以被缓冲。clog中的信息存放在缓冲区中,缓冲区满后或遇endl时向显示器输出。注意这一点与cerr的不同。在某些系统中,由于缓冲,使用clog代替cerr可以改进显示速度。102. 用流成员函数输出字符用流成员函数输出字符ostream中提供专用于输出单个字符的成员函数 put:put成员函数原型为: ostream &

8、amp;put(char);其参数是字符型数据,可以是字符的ASCII码,也可以是整数或整型表达式。其作用为:将字符或以该整数为ASCII码的字符显示在屏幕上。例如: cout.put(A); /结果是在屏幕上显示一个字符A cout.put(65); /结果是在屏幕上同样显示一个字符 A,因为65是A的 ASC 码113.用控制符控制输出格式用控制符控制输出格式控制符控制符作用作用endl 输出时插入换行符并刷新流输出时插入换行符并刷新流ends输出时在字符串后插入结束符输出时在字符串后插入结束符NULLflush刷新缓冲区刷新缓冲区 ws暂时略去前导的空白字符暂时略去前导的空白字符(空格、

9、空格、tab键、换行键、换行)dec设置整数的基数为设置整数的基数为10 (默认数制默认数制) hex 设置整数的基数为设置整数的基数为16oct设置整数的基数为设置整数的基数为8setbase(int n)设置数制转换基数为设置数制转换基数为n(n只能是只能是8、10、16三者之一三者之一)setfill(char c)设置填充字符设置填充字符c.(c可以是字符常量或字符变量可以是字符常量或字符变量)setprecision(it n)设置浮点精度为设置浮点精度为n (设置小数位数,包括小数点设置小数位数,包括小数点)setw(int n)设置字段宽度为设置字段宽度为n位位setiosfla

10、gs(格式标志格式标志)设置特定格式,具体格式标志作用见下表设置特定格式,具体格式标志作用见下表10-3resetiosflags(格式标志格式标志)取消已设置特定格式,具体格式标志作用见下表取消已设置特定格式,具体格式标志作用见下表10-312表表10-1 输入输出控制符输入输出控制符【例10-1】控制符的使用示例 /*10-1.cpp*/#include#includeint main( )int x=123;double y=-12.345678;coutx=setw(10)x;couty=setw(10)yendl;coutsetiosflags(ios:left); /设置按左对齐输

11、出coutx=setw(10)x;couty=setw(10)yendl;coutsetfill(001); /设置填充字符为001coutsetprecision(3); /设置浮点数输出精度为313coutx=setw(10)x;couty=setw(10)yendl;coutresetiosflags(ios:left); / 取消按左对齐输出coutsetfill( ); /恢复填充字符为空格coutsetiosflags(ios:scientific); /设置按科学表示法输cout x=xy=yendl;coutsetiosflags(ios:fixed); /设置按定点表示法输出

12、coutsetiosflags(ios:showpos); /设置正数的正号输出cout x=xy=yendl;coutresetiosflags(ios:showpos);/ 取消输出正数的正return 0;14运行结果:运行结果:【例【例10-2】使用控制符输出不同进制的整数】使用控制符输出不同进制的整数 /*10-2.cpp*/#include #includeint main( )int x=30;cout x = xendl; /按十进制输出coutoct x = xendl; /按八进制输出couthex x = x endl; /按十六进制输出coutsetiosflags(i

13、os:uppercase); /数值中的字母大写输出cout x = xendl; /仍按十六进制输出,但字母大写 coutresetiosflags(ios:uppercase);/取消数值中的字母大写输出cout x = xendl; /仍按十六进制输出,但字母小写 return 0;15运行结果:运行结果:4. 用流成员函数控制输出格式用流成员函数控制输出格式流成员函数流成员函数作用作用int width();返回当前显示数据的域宽返回当前显示数据的域宽int width(int n);设置当前显示数据域宽并返回原域宽为设置当前显示数据域宽并返回原域宽为nchar fill(); 返回当

14、前填充字符返回当前填充字符char fill(char c);设置填充字符并返回原填充字符为设置填充字符并返回原填充字符为cint precision();返回当前浮点数精度返回当前浮点数精度int precision(int n);设置浮点数精度井返回原精度为设置浮点数精度井返回原精度为nsetf(格式标志格式标志)设置特定格式,具体格式标志作用见下表设置特定格式,具体格式标志作用见下表10-3unsetf(格式标志格式标志)取消设置特定格式,具体格式标志作用见下表取消设置特定格式,具体格式标志作用见下表10-316表10-2 用于控制输入输出的流成员函数格式标志格式标志作用作用ios: f

15、ixed设置固定的浮点显示设置固定的浮点显示ios: scientific设置指数形式表示设置指数形式表示ios: lef输出数据左对齐输出数据左对齐ios: right输出数据右对齐输出数据右对齐ios: upcase以十六进制大写形式表示以十六进制大写形式表示ios: lowercase以十六进制小写形式表示以十六进制小写形式表示ios: showpos输出正数时给出输出正数时给出“+”号号17表10-3 格式控制标志字列表注意:由于它们是在公用成员部分定义的,所以其中的每个枚举类型常量在加上 ios:前缀后,就可以为本类成员函数和所有外部函数访问。【例【例10-3】使用成员函数实现例】使

16、用成员函数实现例10.1的同样输出效果的同样输出效果 /*10-3.cpp*/#include#includeint main( )int x=123;double y=-12.345678;cout x = ;cout.width(10); /设置输出下一个数据的域宽为10coutx; /按缺省的右对齐输出,剩余位置填充空格字符cout y = ;cout.width(10); /设置输出下一个数据的域宽为10coutyendl;cout.setf(ios:left); /设置按左对齐输出18cout x = ;cout.width(10);coutx;cout y = ;cout.widt

17、h(10);coutyendl;cout.fill(001); /设置填充字符为$cout.precision(3); /设置浮点数输出精度为3cout x = ;cout.width(10);coutx;cout y = ;cout.width(10);19coutyendl;cout x = x ;cout y = ;cout.setf(ios:scientific); /设置按科学表示法输出coutyendl;cout x = ;cout.setf(ios:showpos); /设置正数的正号输出coutx;cout y = ;cout.setf(ios:fixed);coutyendl

18、;cout.unsetf(ios:showpos); / 取消输出正数的正号return 0;20【例10-4】使用成员函数实现例10-2的同样输出效果 /*10-4.cpp*/#include#includeint main( )int x=30;cout x = xendl; /按十进制输出cout x = ;cout.unsetf(ios:dec); /取消十进制输出设置cout.setf(ios:oct); /设置为八进制输出coutxendl; /按八进制输出cout x = ;cout.unsetf(ios:oct); /取消八进制输出设置,恢复按十进制输出cout.setf(io

19、s:hex); /设置为十六进制输出21coutxendl; /按十六进制输出cout x = ;cout.setf(ios:uppercase); /设置数值中的字母大写输出coutxendl;cout.unsetf(ios:uppercase); /取消数值中的字母大写输出cout x = xendl;cout.unsetf(ios:hex); /取消十六进制输出设置,恢复按十进制输出return 0;2210.2.3 标准输入流标准输入流1. cin流流cin 是类 istream 的对象,即标准输入流,在不作其它说明条件下,与标准输入设备(一般指键盘)相关联。 使用时要注意: (1)

20、一般情况下提取运算符作用于 cin 对象。 (2) 也可以自己构造输入流对象,例如:istream obj;。 (3) 输入语句中可以串联多个提取运算符,每个提取符后为一表达式,该表达式是获得输入值的变量和对象。(4) 提取操作时,空白符(空格、tab键、换行符)只用于字符的分隔符,其本身不作为从输入流中提取的字符。 (5) 提取运算符可以从输入流中读取一个字符串,该字符串是以空白符结束的一个字符序列,由系统自动加上0字符。232 . 用流成员函数输入字符(1) 用流成员函数getline输入字符其函数原型为:getline(chiar *str,int size,char=n); 第一个参数

21、是字符数组,用于存放整行文本,第二个参数是读取的最大字符个数,第三个参数是作为界限的字符,默认是n换行符,如果是其他的符号亦可。其用法共有三种::getline(chiar *str,int size); 其作用为:如果指定输入流中的数据个数大于等于size,则从其中提取(size-1)个字符,赋给指针指向的字符数组,然后在数组第size个位置加入字符串结束标志0。24 getline(chiar *str,char=n);其作用为:从指定的输入流中提取字符,遇到指定中止字符(回车)时结束,然后将这些字符放入字符数组,并且在最后一个字符的下一个位置加入字符串结束标志0。 getline(chi

22、ar *str,int size,char=n);其作用为:从指定输入流中提取(size-1)个字符,赋给指针指向的字符数组,然后在数组第size个位置加入字符串结束标志0。如果提取(size-1)个字符之前遇到指定中止字符(回车),则提前结束,并且在最后一个字符的下一个位置加入字符串结束标志0。25【例【例10-5】从键盘上输入不同个数的字符,按不同的规律接收。】从键盘上输入不同个数的字符,按不同的规律接收。 /*10-5.cpp*/#include int main( ) char str5; cin.getline(str,sizeof(str),n); coutstrendl; ret

23、urn 0;26 当输入字符个数小于4便按下回车:再次运行程序,当输入字符个数大于4再按下回车:27(2) 用流成员函数get输入字符在输入时有可能每次只需要输入单个字符,这时候我们可以使用get( )成员函数来实现。函数原型为:get (char *str,int size,char=n);参数含义与getline( )相同。其用法共有五种:get ( ); 其作用为:从指定的输入流中提取一个字符,其返回值可作为右值。28get(char ch);其作用为:从指定的输入流中提取一个字符,然后赋给ch。例如: char ch; get(ch); /可从输入设备中提取字符,赋给chget(cha

24、r *str,int size);其作用与getline(char *str,int size) ;基本相同。get(chiar *str,char=n);其作用与getline(char *str ,char=n) ;基本相同。get(char *str,int size,char=n);其作用与getline(char *str,int size,char=n); 基本相同。2910.3 插入和提取运算符的重载插入和提取运算符的重载10.3.1 系统预先对插入和提取运算符的重载系统预先对插入和提取运算符的重载预定义插入、提取运算符的语法格式如下:ostream & ostream:

25、operator (简单修饰符 & ) 简单类型为char, int, short, long,unsigned,signed类型,以及float,double,long double,char *类型,标识符除了简单修饰符与在istream流类中声明操作符重载函数给出的所有简单类型标识符相同以外,还增加一个void* 类型,用于输出任何指针(但不能是字符指针,因为它将被作为字符串处理,即输出所指向存储空间中保存的一个字符串)的值。30由于运算符重载函数“operator ”返回的是引用“ostream &”,可达到作为左值的目的,起到一个ostream 类型的独立对象的作用,

26、从而可知如下两种使用方式的合法性与等同性:(cout.operator(x).operator(y); /函数调用方式coutx(x).operator(y); /函数调用方式cinxy; /运算符调用方式3110.3.2 用户自定义对插入和提取运算符的重载用户自定义对插入和提取运算符的重载运算符重载有两种形式:重载为成员函数或者是重载为友元函数。但由于重载插入运算符和提取运算符时,其左边的参数是流,而右边的参数是类的对象,因此,插入运算符和提取运算符只能重载为友元函数。 插入与提取运算符的重载一般格式如下: friend ostream& operator(istream&

27、in, object& obj); / object 为用户自定义类类型其中的 “operator” 则用于完成从 istream 类的流类对象 in 上,输入一个用户自定义类型的数据放入 object 型引用对象 obj 中。32【例10-6】自定义一个复数类complex,其中要重载用于完成复数输入输出的运算符“”,以实现直接对该自定义类的对象进行输入与输出的操作。 /*10-6.cpp*/#includeclass Complex /自定义的简单复数类Complex public:Complex(double r=0, double i=0) /构造函数,并设置参数默认值 rea

28、l=r; imag=i; private:double real; /复数实部double imag; /复数虚部33friend istream & operator (istream & in, Complex & cp) /以友元方式重载输入运算符,输入复数incp.realcp.imag;return in; /该return 语句不可缺少(因为函数返回类型为istream&)friend ostream& operator (ostream& out, Complex cp) /以友元方式重载输出运算符,输出复数outcp.real +

29、 cp.imagi endl;return out; /该return 语句不可缺少(因为函数返回类型为ostream&); 34int main( ) Complex c1(1,1), c2(2,3), c3;cout c1 = c1 c2 = c2; /调用operator 运算符重载函数cout Please Input c3: c3; /调用operator 运算符重载函数cout c3 = c3;return 0;35有以下两点注意注意:函数的输入输出语句中出现的类对象cout以及cin ,正是输入输出重载函数中引用型形参out以及in的对应实参。也就是说,若使用“coutc

30、1;”它将等同于“operatorc3;”则等同于使用“operator(cin,c3);”。本程序调用自定义的“operator ”和“operator ”运算符重载函数时,其第一实参使用的是类对象 cout 和 cin。实际上,第一实参也可使用 fstream 类的类对象(对应于一个磁盘文件),那时的输入输出将与磁盘文件相关联(而不再是键盘与屏幕)。3610.4 文件的输入输出文件的输入输出10.4.1 文件及分类文件及分类所谓“文件文件”,一般指存储在外部介质数据的集合。根据文件中数据的组织形式,可分为ASCII文件文件和二进制二进制文件文件。ASCII文件文件又称文本(text)文件或

31、字符文件,它的每一个字节放一个ASCII代码代表一个字符。二进制文件二进制文件又称内部格式文件或字节文件,是把内存中数据按存储形式原样输出到磁盘上存放。C+对文本文件操作时,先进行二进制形式与ASCII 码的转换,将转换后的数据进行输入输出。C+对二进制文件操作时,不进行转换,直接以二进制形式进行输入输出。3710.4.2 文件的打开与关闭文件的打开与关闭1. 文件的打开文件的打开ofstream类的默认构造函数原形为:ofstream:ofstream(const char *filename,int mode=ios:out,int openprot= filebuf:openprot);

32、 参数filename为要打开的文件名,mode为要打开文件的方式 ,openprot为要打开文件的属性 。mode和openprot这两个参数的可选项表见表10-4和表10-5所示。38mode属性属性含义含义ios:app 以追加的方式打开文件以追加的方式打开文件ios:ate文件打开后定位到文件尾,文件打开后定位到文件尾,ios:app就包含有此属性就包含有此属性 ios:binary以二进制方式打开文件,缺省的方式是文本方式。两种方式的区别见前文以二进制方式打开文件,缺省的方式是文本方式。两种方式的区别见前文ios:in文件以输入方式打开文件以输入方式打开 ios:out文件以输出方式

33、打开文件以输出方式打开 ios:trunc如果文件存在,把文件长度设为如果文件存在,把文件长度设为039表表10-4 mode属性表属性表属性值属性值含义含义0普通文件,打开访问普通文件,打开访问 1只读文件只读文件 2隐含文件隐含文件 4系统文件系统文件表表10-5 openprot 属性表属性表注意:可以用“或”把以上属性连接起来,如 ios:out|ios:binary。2文件的关闭在对已打开的磁盘文件的读写操作完成后,应关闭该文件。所谓关闭,实际上是解除该磁盘文件与文件流的关联,原来设置的工作方式失效,也就是不能再通过文件流对该文件进行输入输出。 每个文件流类中都提供有一个关闭文件的成

34、员函数close(),只有当打开的文件操作结束关闭后,才能够保证最后输出到文件缓冲区中的内容,无论是否已满,都可立即写入到对应的物理文件中。文件流对应的文件被关闭后,还可以利用该文件流调用open成员函数打开其他的文件。4010.4.3 文本文件操作文本文件操作1.使用插入运算符和提取运算符对文本文件输入、输出操作(1) 插入运算符重载: ostream& operator(简单类型 &);“”左边是文件流对象,“”右边是输出到该文件流中的数据项。ofstream f1(“abc.txt”); /建立输出到文件流对象f1f1i(简单类型 &);2. 使用成员函数对文本文

35、件输入输出操作(1) 调用put成员函数: ostream &put(char); 向文本文件输出数据。41【例10-7】向文件中写入09十个整数。 /*10-7.cpp*/#includevoid main( )ofstream f1(abc.txt );if ( !f1 )cerrabc. txt file can not open!endl; return;for(int i=0;i10;i+) f1i ;f1endl;f1.close();运行后abc.txt文件内容为:0 1 2 3 4 5 6 7 8 942(2) 调用get( )成员函数对文本文件输入 int get(

36、); istream &get(char &);(3) 调用getline(char *buffer,int len,char=n)成员函数对文本文件输入【例【例10-8】从键盘上输入字符,放入文本文件,按下回】从键盘上输入字符,放入文本文件,按下回车时结束。车时结束。 /*10-8.cpp*/#includevoid main( ) char ch; ofstream f1(abc. txt );43if( f1.fail( ) )cerr abc. txt file can not open!endl;return; ch=cin.get( );while(ch!=n)f1

37、.put(ch);ch=cin.get( );f1.close( );运行结果:abcdefg运行后文件abc.txt 中内容为:abcdefg4410.4.4 二进制文件操作二进制文件操作对二进制文件的读写可采用两种方法:对二进制文件的读写可采用两种方法:1. 类成员函数get与put2. 类成员函数read 与write(主要方式)对二进制文件进行读写通常使用read与write类成员函数 。read 与write 类成员函数的常用格式及功能如下:ostream:writeostream & write( const char * p, int n );功能:将 p 缓冲区中的前

38、n 个字符写出到某个文件(ostream 流对象)中。istream:readistream & read( char *p, int n );功能:从某个文件(istream 流对象)中读入 n 个字符放入 p 缓冲区中(若读至文件结束尚不足n 个字符时,也将立即结束本次读取过程)。45【例【例10-9】使用成员函数 write 或 put 将数据写入文件“abc.txt”中,并统计且显示出输出符号的个数。/*10-9.cpp*/#include #include int main( ) char str80; int i=0;coutPlease input the string:

39、endl;gets(str); /从键盘输入字符串(以换行结束输入)ofstream fout(abc.dat);while(stri+) fout.write(str, sizeof(str);/通过将str 中各字符写到文件中/如果 使用成员函数put 形式为:while(stri)fout.put(stri); i+;coutlen=(i-1)endl; /显示输出符号的个数,不包括结束符fout.close();return 0;46运行结束后文件中为:C+ Program10.5 字符串流操作字符串流操作字符串流也叫内存流。严格来说,把字符串流的输入输出操作说成字符串流在内存中的移动更恰当。字符串流就是能够控制字符串类型对象进

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论