C++教程11-输入输出流课件_第1页
C++教程11-输入输出流课件_第2页
C++教程11-输入输出流课件_第3页
C++教程11-输入输出流课件_第4页
C++教程11-输入输出流课件_第5页
已阅读5页,还剩159页未读 继续免费阅读

下载本文档

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

文档简介

第十一章

输入/输出流第十一章输入/输出流学习目标掌握C++输入/输出流(I/O流)的基本概念;能够在输入/输出中进行基本的格式控制;掌握文件的I/O操作。2学习目标掌握C++输入/输出流(I/O流)的基本概念;2目录11.1C++输入输出流的概念11.1.1什么是输入输出流11.1.2流类库的头文件11.1.3预定义流对象11.1.4I/O流库的类体系11.1.5输出流举例11.1.6输入流举例3目录11.1C++输入输出流的概念3目录(续)11.2无格式的输入/输出11.2.1无格式输入11.2.2无格式输出11.3有格式的输入/输出11.3.1默认的输入/输出格式11.3.2格式标志的设置11.3.3格式控制操纵符11.4I/O流的状态4目录(续)11.2无格式的输入/输出4目录(续)11.5文件流11.5.1文件的概念11.5.2文件流的建立11.5.3文件流的关闭11.5.4两种特殊的文件流11.6字符串流11.6.1字符串流的建立11.6.2字符串流的缓冲区操作11.7针对自定义类型重载>>和<<5目录(续)11.5文件流511.1.1什么是输入/输出流C++将数据从一个对象到另一个对象的流动抽象为“流”。在程序中,“流”具体体现为一个对象,负责在数据生产者和数据消费者之间建立联系,控制数据的流动。例如cin、cout就是两个流对象。利用I/O流既可进行有格式输入/输出,也可进行无格式输入/输出。为了实现格式化的输出,I/O流类库提供了丰富的流操纵符,比如设置输出域的宽度,设置输出精度,设置填充字符等。611.1

C++输入输出流的概念11.1.1什么是输入/输出流C++将数据从一个对象到另一11.1.2流类库的头文件<iostream>:

包括istream、ostream、iostream以及cin、cout、ceer和clog对象的定义,同时提供非格式化和格式化的I/O服务。针对标准设备的I/O操作,须包含之。<sstream>:

包括istringstream、ostringstream、stringstream的定义,要使用字符串流对象进行针对内存字符串空间的I/O操作,须包含此文件。<fstream>:

包括ifstream、ofstream、fstream的定义,要使用文件流对象进行针对磁盘文件的I/O操作,须包含此文件。<iomanip>:

包括setw、fixed等等操纵符的定义,利用操纵符进行格式化I/O操作,须包含之。711.1

C++输入输出流的概念11.1.2流类库的头文件<iostream>: 711.11.1.3预定义流对象C++中一共有4个预定义流对象,它们的名称及与之联系的I/O设备如下:cin 标准输入流对象,对应标准输入设备

cout 标准输出流对象,对应标准输出设备

cerr 标准错误信息输出流对象,对应标准出错信息输出设备

clog 标准错误信息输出流对象,对应带缓冲的标准出错信息输出设备这里提到的标准输入设备和标准输出设备是操作系统下的两种虚拟设备,每种虚拟设备都与一种具体的设备相连接。通常情况下,标准输入设备与键盘相连接,标准输出设备与显示器相连接,但可以重定向为与其他设备(如磁盘)。在程序中可以定义自己的流对象(称为自定义流对象),以满足特定输入、输出需求。811.1

C++输入输出流的概念11.1.3预定义流对象C++中一共有4个预定义流对象,它11.1.4I/O流库的类体系I/O流库的类体系C++通过一系列的流类将不同类型数据的输入/输出操作封装起来,以面向对象的方式规范各种输入/输出操作,提供了一套简化的操作界面,使得不同类型的数据的输入/输出可以采用相同的语法格式。部分流类之间的继承关系如图。911.1

C++输入输出流的概念11.1.4I/O流库的类体系I/O流库的类体系911.111.1.5输出流举例一个输出流对象是信息流动的目标,最重要的三个输出流是ostream、ostringstream和ofstream。ostream是通用输出流类,cout、cerr和clog都是它的对象;ostringstream是字符串输出流类,它将一片内存空间作为输出设备;ofstream是文件输出流类。1011.1

C++输入输出流的概念11.1.5输出流举例一个输出流对象是信息流动的目标,最重例11-1:向标准设备输出字符串#include<iostream>usingnamespacestd;intmain(){

char*word="helloworld!";

doublepi=3.1415926;

intdayOfYear=365;

cout<<"valueofwordis:"<<word<<endl;

cout<<"PI="<<pi<<endl;

cout<<"daysofyear:"<<dayOfYear<<endl;

cout.put('B').put('C').put('\n');

return0;}1111.1输入输出流的概念——11.1.5输出流举例例11-1:向标准设备输出字符串#include<iost运行结果:valueofwordis:helloworld!PI=3.14159daysofyear:365BC例11-1(续)11.1输入输出流的概念——11.1.5输出流举例运行结果:例11-1(续)11.1输入输出流的概念——1111.1.6输入流举例最重要的三个输入流istream、istringstream和ifstream。Istream是通用输入流类,cin即为它的对象;istringstream是字符串输入流类,它将一片内存空间作为输入设备;ifstream是文件输入流类。cin是预定义的标准输入流对象。get()函数从指定流输入一个字符并将这个值作为函数调用的返回值返回,在遇到文件尾时返回EOF。如果用流提取运算符>>,注意流提取运算符遇到空格就结束。1311.1

C++输入输出流的概念11.1.6输入流举例最重要的三个输入流1311.1C+例11-2:输入字符串#include<iostream>usingnamespacestd;intmain(){

intcharacter;

cout<<"beforeinput,cin.eof()="<<cin.eof()<<endl;

cout<<"pleaseinputasentence:"<<endl;

while((character=cin.get())!=EOF)

cout.put(character);

cout<<"EOFinthissystemis:"<<character<<endl;

cout<<"afterinputofEOF,cin.eof()="<<cin.eof()<<endl;

return0;}1411.1输入输出流的概念——11.1.6输入流举例例11-2:输入字符串#include<iostream>运行结果:beforeinput,cin.eof()=0pleaseinputasectence:IamagoodC++programmerIamagoodC++programmer^ZEOFinthissystemis:-1AfterinputofEOF,cin.eof()=1例11-2(续)11.1输入输出流的概念——11.1.6输入流举例15运行结果:例11-2(续)11.1输入输出流的概念——11例11-3:输入指定长度的字符串#include<iostream>usingnamespacestd;intmain(){

constintSIZE=80;

charbuf1[SIZE];

charbuf2[SIZE];

cout<<"pleaseinputasentence:"<<endl;

cin>>buf1;

cout<<"thestringreadwithcinwas:"<<endl<<buf1<<endl;

cin.get(buf2,SIZE);

cout<<"thestringreadwithcin.getwas:"<<endl<<buf2<<endl;

return0;}1611.1输入输出流的概念——11.1.6输入流举例例11-3:输入指定长度的字符串#include<iost运行结果:pleaseinputasectence:heisaC++programmerthestringreadwithcinwas:hethestringreadwithcin.getwas:isaC++programmer例11-3(续)11.1输入输出流的概念——11.1.6输入流举例17运行结果:例11-3(续)11.1输入输出流的概念——1111.2无格式的输入输出无格式输入/输出是一种内存映像式的输入/输出,不对数据做任何转换,也称为二进制输入/输出,打开文件的模式为ios_base::binary。无格式输入/输出主要针对二进制磁盘文件,不能针对打印机、显示器等字符设备。cin、cout等预定义流对象不能用于无格式输入/输出。1811.2无格式的输入输出无格式输入/输出是一种内存映像式的11.2无格式的输入输出(续)在下面有关函数的说明中用到一些类型定义,包括:streamsize:表示流大小的类型,一般就是int或long;int_type:整数类类型,一般就是int或long;istream_type:输入流类型,一般就是istream;ostream_type:输出流类型,一般就是ostream;char_type:字符类类型,一般就是char;off_type:偏差(相对位置)类型,一般就是long;pos_type:位置类型,一般就是long。1911.2无格式的输入输出(续)在下面有关函数的说明中用到一11.2.1无格式的输入与无格式输入有关的类包括istream、istringstream和ifstream这三个输入流类,以及stream、stringstream和fstream这三个输入/输出流类。无格式输入有关的函数streamsizegcount()const;返回最近一次无格式输入的字节数。int_typeget();返回提取的当前输入位置的字符(不会跳过空白字符),若已到流尾而无字符可输入,返回EOF(即-1);istream_type&get(char_type&c);提取当前输入位置的字符(不会跳过空白字符)存入c,若已到流尾而无字符可输入,存入c中的是'\0'。istream_type&get(char_type*s,streamsizen,char_typedelim);从当前输入位置开始提取字符存入s所指的具有n个字节的字符空间中。2011.2无格式的输入输出11.2.1无格式的输入与无格式输入有关的类2011.211.2.1无格式的输入(续)无格式输入有关的函数istream_type&get(char_type*s,streamsizen);

此函数调用

get(s,n,widen(‘\n’)),即已换行符为分界符,用以输入一行字符,参见上面关于get函数的描述。istream_type&ignore(streamsizen=1,int_typedelim=traits::eof());

提取并舍弃(即不存储)从当前输入位置开始的若干字符,因而只起到后移输入位置的作用。int_typepeek();

返回当前位置上的字符,但输入位置不动,因此下一次输入字符时,得到还是同一字符。若已到流尾而无字符可输入,返回EOF(即-1)。istream_type&unget();

使输入位置倒退一个字符,使得上次被输入的字符再次成为下一个输入字符。istream_type&read(char_type*s,streamsizen);

从当前输入位置开始提取字节存入s所指的具有n个字节的字符空间中。2111.2无格式的输入输出11.2.1无格式的输入(续)无格式输入有关的函数211111.2.2无格式的输出与输出有关的类包括ostream、ostringstream和ofstream这三个输出流类,以及stream、stringstream和fstream这三个输入/输出流类。与无格式输出有关的函数ostream_type&put(char_typec);输出字符costream_type&write(constchar_type*s,streamsizen);输出s所指向的数据空间中的n个字节

2211.2无格式的输入输出11.2.2无格式的输出与输出有关的类2211.2无格式11.3.1默认的输入/输出格式运算符>>默认的输入格式short、int、long(signed、unsigned):与整型常量同;float、double、longdouble:与浮点数常量同;char(signed、unsigned):第一个非空白字符;char*(signed、unsigned):从第一个非空白字符开始到下一个空白字符结束;bool:将true或1识别为逻辑真(true),其他的均识别为逻辑假(false);void*:无前缀的16进制数。2311.3有格式的输入输出11.3.1默认的输入/输出格式运算符>>默认的输入格式2311.3.1默认的输入/输出格式(续)运算符<<默认的输出格式char(signed、unsigned):单个字符(无引号)short、int、long(signed、unsigned):一般整数形式,负数前有-号char*(signed、unsigned):字符序列(无引号)float、double、longdouble:浮点格式或指数格式(科学表示法),取决于哪个更短

void*:无前缀的16进制数Bool:1或02411.3有格式的输入输出11.3.1默认的输入/输出格式(续)运算符<<默认的输出格11.3.2格式标志的设置2511.3有格式的输入输出11.3.2格式标志的设置2511.3有格式的输入输出11.3.2格式标志的设置(续)2611.3有格式的输入输出11.3.2格式标志的设置(续)2611.3有格式的输入11.3.3格式控制操纵符控制数制的操纵符:Dec功能:(初始状态)将整数按10进制输入/输出;

等价函数调用:io.setf(ios_base::dec,ios_base::basefield)Oct功能:将整数按8进制输入/输出;

等价函数调用:io.setf(ios_base::oct,ios_base::basefield)Hex功能:将整数按16进制输入/输出;

等价函数调用:io.setf(ios_base::hex,ios_base::basefield)setbase(base)功能:设置为指定的数制,其中base为8、10或16;

等价函数调用:io.setf(ios_base::oct,ios::basefield)等控制数制标志输出的操纵符:showbase功能:为输出的整数生成一个表示数制的前缀:对于八进制数前面输出一个无效0;对于十六进制数前面输出0x;

等价函数调用:o.setf(ios_base::showbase)noshowbase功能:(初始状态)输出的整数没有表示数制的前缀

等价函数调用:o.unsetf(ios_base::showbase)2711.3有格式的输入输出11.3.3格式控制操纵符控制数制的操纵符:2711.311.3.3格式控制操纵符(续)控制数制标志中字母X的大小写的操纵符:Uppercase功能:将输出的十六进制数据(包括表示数制的前缀)中的字母以大写形式表示(如0X3F);

等价函数调用:o.setf(ios_base::uppercase)nouppercase功能:(初始状态)将输出的十六进制数据(包括表示数制的前缀)中的字

母以小写形式表示(如0x3f)。

等价函数调用:o.unsetf(ios_base::uppercase))2811.3有格式的输入输出11.3.3格式控制操纵符(续)控制数制标志中字母X的大小例11-4:输入/输出的数制控制示例#include<iostream>#include<iomanip>usingnamespacestd;

intmain(){

inti,j;

cin>>hex>>i>>showbase>>j;

cout<<i<<'\t'<<j;

cout<<endl<<oct<<i<<'\t'<<showbase<<j<<endl;

return0;}2911.3有格式的输入输出——11.3.3格式控制操作符例11-4:输入/输出的数制控制示例#include<ios运行结果:63250770372例11-4(续)11.3有格式的输入输出——11.3.3格式控制操作符30运行结果:例11-4(续)11.3有格式的输入输出——1111.3.3格式控制操纵符(续)输入/输出宽度的控制宽度控制是一种与格式标志无关的控制。宽度的设置可用于输入,但只对字符串输入有效。对于输入,宽度是指字符串空间的宽度,由于要存储字符串结束符’\0’,因此实际可接收的输入字符数比宽度少1。对于输出,宽度是指最小输出宽度。当实际数据宽度小于指定的宽度时,多余的位置用填充字符(通常是空格)添满;当实际数据的宽度大于设置的宽度时,仍按实际的宽度输出。初始宽度值为0,意味着所有数据都将按实际宽度输入/输出。宽度设置的效果没有延续性,只对一个数据的输入或输出有效,在完成一个数据的输入或输出后,又回到初始宽度值0,即按实际数据宽度输入或输出。有关的操纵符是:setw(n) 功能:设置输入/输出宽度,其中n为表示宽度的整数;等价函数调用:io.width(n)3111.3有格式的输入输出11.3.3格式控制操纵符(续)输入/输出宽度的控制311例11-5:输入/输出宽度控制示例#include<iostream>#include<iomanip>usingnamespacestd;

intmain(){

chars1[20],s2[20];

cin>>setw(5)>>s1>>s2;

cout<<setw(8)<<s1<<'!'<<endl;

cout<<s1<<'!'<<endl;

cout<<setw(8)<<s2<<'!'<<endl;

return0;}3211.3有格式的输入输出——11.3.3格式控制操作符例11-5:输入/输出宽度控制示例#include<iost运行结果:abcd!abcd!efghijklmnop!例11-5(续)11.3有格式的输入输出——11.3.3格式控制操作符33运行结果:例11-5(续)11.3有格式的输入输出——1111.3.3格式控制操纵符(续)输出精度的控制精度的控制是一种与格式标志无关的控制。精度是针对浮点数设置的,精度设置对于输入流无效。对于输出流,初始精度值为6,可以通过设置改为任意精度;将精度设置0意味着回到初始精度6。有关操纵符是:setprecision(n) 功能:设置浮点数的精度,其中n为精度的整数;等价函数调用:o.precision(n),函数返回此前设置的精度;如果只需要这个返回值,可不给出参数。3411.3有格式的输入输出11.3.3格式控制操纵符(续)输出精度的控制3411.311.3.3格式控制操纵符(续)浮点数输出方式的控制浮点数都按浮点格式输出,精度的含义是有效位的个数,小数点的相对位置随数据的不同而浮动;可以改变设置,使浮点数按定点格式或指数格式

(科学表示法,如3.2156e+2)输出。在这种情况下,精度的含义是小数位数,小数点的相对位置固定不变,必要时进行舍入处理或添加无效0。有关操纵符有:resetiosflags(ios_base::floatfield)功能:(初始状态)浮点数按浮点格式输出;

等价函数调用:o.setf(0,ios_base::floatfield)fixed 功能:浮点数按定点格式输出;

等价函数调用:o.setf(ios_base::fixed,ios_base::floatfield)scientific功能:浮点数按指数格式(科学表示法)输出;

等价函数调用:o.setf(ios_base::scientific,ios_base::floatfield)3511.3有格式的输入输出11.3.3格式控制操纵符(续)浮点数输出方式的控制351例11-6:设计函数sqrt_table(),它输出一个平方根表,其中包含了所有不超过两位数的平方根,精确到小数点后4位3611.3有格式的输入输出——11.3.3格式控制操作符例11-6:设计函数sqrt_table(),它输出一个平方例11-6(续)#include<iostream>#include<iomanip>#include<cmath>usingnamespacestd;

voidsqrt_table(){

cout<<endl<<"|";

inti;//以下3行显示顶部表栏

for(i=0;i<10;i++)cout<<setw(7)<<i;cout<<endl<<"---+----------------------------------------------------------------------";

cout<<fixed<<setprecision(4); //设置为定点格式和4位精度

for(i=0;i<10;i++){ //十位数从0循环到9

cout<<endl<<setw(2)<<i<<"|“; //显示左部表栏

for(intj=0;j<10;j++)cout<<setw(7)<<sqrt(i*10.0+j);

}

cout<<endl;}intmain(){

sqrt_table();

return0;}3711.3有格式的输入输出——11.3.3格式控制操作符例11-6(续)#include<iostream>3711运行结果:|0123456789--+----------------------------------------------------------------------------------------0|0.00001.00001.41421.73212.00002.23612.44952.64582.82843.00001|3.16233.31663.46413.60563.74173.87304.00004.12314.24264.35892|4.47214.58264.69044.79584.89905.00005.09905.19625.29155.38523|5.47725.56785.65695.74465.83105.91616.00006.08286.16446.24504|6.32466.40316.48076.55746.63326.70826.78236.85576.92827.00005|7.07117.14147.21117.28017.34857.41627.48337.54987.61587.68116|7.74607.81027.87407.93738.00008.06238.12408.18548.24628.30667|8.36668.42618.48538.54408.60238.66038.71788.77508.83188.88828|8.94439.00009.05549.11049.16529.21959.27369.32749.38089.43409|9.48689.53949.59179.64379.69549.74689.79809.84899.89959.9499例11-6(续)11.3有格式的输入输出——11.3.3格式控制操作符38运行结果:例11-6(续)11.3有格式的输入输出——1111.3.3格式控制操纵符(续)小数点处理方式的控制

此设置只影响采用浮点格式(而非定点格式或指数格式)输出的浮点数据。在初始状态下,若一浮点数的小数部分为0,则不输出小数点及小数点后的无效0;可以改变这一设置,使得在任何情况下都输出小数点及其后的无效0。有关操纵符有:showpoint功能:即使小数部分为0,也输出小数点及其后的无效0;

等价函数调用:o.setf(ios_base::showpoint)noshowpoint 功能:(初始状态)取消上述设置:小数部分为0时不输出小数点;

等价函数调用:o.unsetf(ios_base::showpoint)3911.3有格式的输入输出11.3.3格式控制操纵符(续)小数点处理方式的控制391例11-7:小数点处理方式控制示例#include<iostream>usingnamespacestd;

intmain(){ cout<<3.0<<showpoint<<""<<3.0<<noshowpoint<<""<<3.0<<endl; cout<<fixed<<3.0<<showpoint<<""<<3.0<<noshowpoint<<""<<3.0<<endl; cout<<scientific<<3.0<<showpoint<<""<<3.0<<noshowpoint<<""<<3.0<<endl;

return0;}4011.3有格式的输入输出——11.3.3格式控制操作符例11-7:小数点处理方式控制示例#include<iost运行结果:33.0000033.0000003.0000003.0000003.000000e+0003.000000e+0003.000000e+000例11-7(续)11.3有格式的输入输出——11.3.3格式控制操作符41运行结果:例11-7(续)11.3有格式的输入输出——1111.3.3格式控制操纵符(续)小数点处理方式的控制对齐方式的控制初始状态为右对齐;可以改变这一设置,使得输出采用左对齐方式或内部对齐方式。只有在设置了宽度的情况下,对齐操作才有意义。有关操纵符有:left功能:在设定的宽度内左对齐输出,右端填以设定的填充字符;

等价函数调用:o.setf(ios_base::left,ios_base::adjustfield)Right功能:(初始状态)在设定的宽度内右对齐输出,左端填以设定的填充字符;

等价函数调用:o.setf(ios_base::right,ios_base::adjustfield)internal功能:(内部对齐)在设定的宽度内右对齐输出,左端填以设定的填充字符;但若有符号(-或+),符号置于设定宽度的最左端;

等价函数调用:o.setf(ios_base::internal,ios_base::adjustfield)4211.3有格式的输入输出11.3.3格式控制操纵符(续)小数点处理方式的控制42111.3.3格式控制操纵符(续)填充字符的控制填充字符控制是一种与格式标志无关的格式控制。在指定的输出宽度内输出数据时,多余的位置要用填充字符填满。初始的填充字符为空格,可以设置任意字符作为填充字符。只有在设置了宽度的情况下,字符填充操作才有意义。有关操纵符是:setfill(c)功能:设置填充字符,其中c为一字符;

等价函数调用:io.fill(c),函数返回此前设置的填充字符;如果只需要这个返回值,可不给参数。4311.3有格式的输入输出11.3.3格式控制操纵符(续)填充字符的控制4311.3例11-8:对齐方式及填充字符控制示意#include<iostream>#include<iomanip>usingnamespacestd;

intmain(){ cout<<setfill('*'); cout<<setw(10)<<-45; cout<<endl<<left<<setw(10)<<-55; cout<<endl<<internal<<setw(10)<<-65<<endl;

return0;}4411.3有格式的输入输出——11.3.3格式控制操作符例11-8:对齐方式及填充字符控制示意#include<io运行结果:*******-45-55*******-*******65例11-8(续)11.3有格式的输入输出——11.3.3格式控制操作符45运行结果:例11-8(续)11.3有格式的输入输出——1111.3.3格式控制操纵符(续)非负数的符号表示方式的控制在初始状态下,0或正数前不用任何符号;可以改变这一设置,使得在0或正数前无条件地加上符号+。有关操纵符有:showpos功能:0或正数前加上符号+;

等价函数调用:o.setf(ios_base::showpos)noshowpos功能:(初始状态)0或正数前不用任何符号;

等价函数调用:o.unsetf(ios_base::showpos)逻辑值输出方式的控制在初始状态下,逻辑值true和false输出为1和0;可以改变设置,使之输出为true和false。有关操纵符有:boolalpha功能:将逻辑值输出为true和false;

等价函数调用:io.setf(ios_base::boolalpha)noboolalpha 功能:(初始状态)取消上述设置:将逻辑值输出为1和0;等价函数调用:io.unsetf(ios_base::boolalpha)4611.3有格式的输入输出11.3.3格式控制操纵符(续)非负数的符号表示方式的控制例11-9:非负数的符号表示方式及逻辑常量输出方式的控制的示意#include<iostream>#include<iomanip>usingnamespacestd;

intmain(){ cout<<0<<'\t'<<5<<'\t'<<-5<<endl; cout<<showpos<<0<<'\t'<<5<<'\t'<<-5<<endl; cout<<noshowpos<<(5>3)<<'\t'<<(5<3)<<endl; cout<<boolalpha<<(5>3)<<'\t'<<(5<3)<<endl;

return0;}4711.3有格式的输入输出——11.3.3格式控制操作符例11-9:非负数的符号表示方式及逻辑常量输出方式的控制的示运行结果:05-5+0+5-510truefalse例11-9(续)11.3有格式的输入输出——11.3.3格式控制操作符运行结果:例11-9(续)11.3有格式的输入输出——1111.3.3格式控制操纵符(续)前导空白字符处理方式的控制

初始状态下,输入一数据时首先跳过前导空白字符。可以通过设置,使得输入时不跳过空白字符。这样的设置一直有效,直到改变设置为止。有关操纵符有:skipws功能:(初始状态)每次输入时跳过前导空白字符;

等价函数调用:i.setf(ios_base::skipws)noskipws功能:每次输入时不跳过前导空白字符;

等价函数调用:i.unsetf(ios_base::skipws)缓冲区工作方式的控制在一般情况下,输出的数据暂存在输出缓冲区中,直到缓冲区满或流被关闭时才送往有关设备有关操纵符有:unitbuf功能:每次输出后立即写缓

等价函数调用:o.setf(ios_base::unitbuf)nounitbuf功能:(初始状态)数据输出到缓冲区暂不写出,待缓冲区满或流被关闭时才写出到所连接的设备中;

等价函数调用:o.unsetf(ios_base::unitbuf)4911.3有格式的输入输出11.3.3格式控制操纵符(续)前导空白字符处理方式的控制11.3.3格式控制操纵符(续)其他输入/输出控制操纵符还有几个操纵符的功能不是格式控制,而是直接执行特定的输入/输出操作。有关操纵符有:Endl功能:插入换行符(即‘\n’)并强制写缓,实现输出回车换行;

等价函数调用:o..put('\n').flush()Ends功能:插入字符串结束符‘\0’,常用于字符串流;

等价函数调用:o.put('\0')Ws功能:在noskipws状态下输入时,用来跳过前导空白字符。Flush功能:强制写缓

等价函数调用:o.flush()5011.3有格式的输入输出11.3.3格式控制操纵符(续)其他输入/输出控制操纵符5例11-10:通过使用文件名“CON”创建输入文件流对象is和输出文件流对象os,用来模拟预定义流对象cin和cout进行针对键盘和显示器的输入/输出5111.3有格式的输入输出——11.3.3格式控制操作符例11-10:通过使用文件名“CON”创建输入文件流对象is例11-10(续)#include<iostream>#include<iomanip>#include<fstream>usingnamespacestd;

intmain(){ intx; ofstreamos("con"); ifstreamis("con");// is.tie(&os); //解决方案3// os<<unitbuf; //解决方案2 os<<"请输入一个整数:";// os<<flush; //解决方案1 is>>x; os<<"输入的整数是:"<<x<<endl;

return0;}5211.3有格式的输入输出——11.3.3格式控制操作符例11-10(续)#include<iostream>521运行结果1:这是所有注释语句行保持原样时的运行结果,其中第一行为键盘输入:123请输入一个整数:输入的整数是:123运行结果2:把标有“解决方案1”、“解决方案2”、“解决方案3”的注释语句中任何一个语句行的行首的//去掉,再运行程序,三次的运行结果相同:请输入一个整数:123输入的整数是:123例11-10(续)11.3有格式的输入输出——11.3.3格式控制操作符53运行结果1:例11-10(续)11.3有格式的输入输出——11.4I/O流的状态C++I/O流的状态用ios_base中一组状态标志位来表示,同时定义了一组判断、操纵这些标志位的成员函数,常用的有boolgood()const:刚进行的操作成功时返回true,否则返回false;boolfail()const:与good()相反,刚进行的操作失败时返回true,否则返回false;boolbad()const:如果进行了非法操作返回true,否则返回false;bad()为true时fail()必为true;booleof()const:进行输入操作时,若到达流尾返回true,否则返回false,通常只用于输入流;eof()为true时fail()必为true;voidclear():将流置为正常状态,使得good()返回true。5411.4I/O流的状态C++I/O流的状态用ios_ba例11-11:错误输入后的错误状态#include<iostream>usingnamespacestd;

intmain(){ intintValue;

cout<<"statebeforeabadinputoperation:"<<endl; cout<<"cin.rdstate():"<<cin.rdstate()<<endl <<"cin.eof():"<<cin.eof()<<endl <<"cin.fail():"<<cin.fail()<<endl <<"cin.bad():"<<cin.bad()<<endl <<"cin.good():"<<cin.good()<<endl;5511.4

I/O流的状态例11-11:错误输入后的错误状态#include<ios例11-11(续)cout<<“expectaninteger,butenteracharacter:”;cin>>intValue; cout<<“stateafterabadinputoperation:”<<endl;cout<<“cin.rdstate():”<<cin.rdstate()<<endl <<“cin.eof():”<<cin.eof()<<endl <<“cin.fail():”<<cin.fail()<<endl <<“cin.bad():”<<cin.bad()<<endl <<“cin.good():”<<cin.good()<<endl;cin.clear();cout<<“stateafterclear:”<<endl;cout<<“cin.fail():”<<cin.fail()<<endl

<<"cin.good():"<<cin.good()<<endl;

return0;}5611.4

I/O流的状态例11-11(续)cout<<“expectaninte运行结果1:statebeforeabadinputoperation:cin.rdstate():0cin.eof():0cin.fail():0cin.bad():0cin.good():1expectaninteger,butenteracharacter:Astateafterabadinputoperation:cin.rdstate():2cin.eof():0cin.fail():1cin.bad():0cin.good():0stateafterclear:cin.fail():0cin.good():1例11-11(续)11.4

I/O流的状态57运行结果1:例11-11(续)11.4I/O流的状态5711.5.1文件的概念磁盘文件以及视作文件的外部设备在磁盘上保存的信息是按文件的形式组织的,每个文件都有一个文件名,并且保存在一个确定的文件夹中。另外,操作系统把其他类型的一些外部设备也以文件的方式进行操作,视作特殊的文件。例如,把由键盘和显示器组成的终端看作为输入/输出文件,当向它输出信息时就是输出到显示器,当从它输入信息时就是从键盘输入。文本文件和二进制文件文本文件可以是磁盘文件,也可以是键盘、显示器、打印机等称为字符设备的外部设备。因此,适用于文本文件的操作也同样适用于键盘、显示器、打印机等设备,而适用于cin、cout等预定义流对象的操作也同样适应于文本文件。可以用文本编辑器来查看、输入、修改一个文本文件。二进制文件只能是磁盘文件。5811.5文件流11.5.1文件的概念磁盘文件以及视作文件的外部设备58111.5.1文件的概念(续)输入文件、输出文件和输入/输出文件

对文件的访问操作包括输入和输出两种类型的操作。如果一个文件是为输入操作而打开的,该文件就称为输入文件。如果一个文件是为输出操作而打开的,就称为输出文件。有的文件打开后既用于输入,也用于输出,则称之为输入/输出文件。5911.5文件流11.5.1文件的概念(续)输入文件、输出文件和输入/输出11.5.2文件流的建立每个文件流都应当与一个打开的文件相联系。可以用两种不同的方式打开文件。 1)在建立文件流对象的同时打开文件

如:ifstreamfin("datafile.dat"); 2)先建立文件流对象,再在适当的时候打开文件,

如:ifstreamfin;…… fin.open("datafile.dat");6011.5文件流11.5.2文件流的建立每个文件流都应当与一个打开的文件相11.5.2文件流的建立(续)可以通过构造函数或open函数的第二个参数,指定文件的打开模式。打开模式被定义为一组枚举常量:

6111.5文件流11.5.2文件流的建立(续)可以通过构造函数或open函11.5.3文件流的关闭关闭文件流用成员函数close().例如若fin是一个文件流对象,则可用下面的语句关闭:fin.close();如果程序没有用close()主动关闭文件,则在文件流对象退出其作用域时,将自动调用文件流对象的析构函数关闭所联系的文件。缓冲区中尚未写入文件的数据将在文件关闭时实际地写入到文件中。当不再使用文件时立即关闭文件是一个好的习惯,这除了能够尽早释放流对象所占用的计算机资源之外,还有利于文件中数据的安全。6211.5文件流11.5.3文件流的关闭关闭文件流用成员函数close()11.5.4两种特殊的文件流以文件名"CON"打开的输入文件流所联系的设备是键盘,可用于键盘输入;以"CON"为文件名打开的输出文件流所联系的设备是显示器,以"CON"为文件名打开的输入/输出文件流所联系的设备是终端,即键盘加显示器。用文件名"PRN"打开的输出文件流所联系的设备是打印机,例如:ofstreamPrinter("PRN");

Print<<"此行文字被打印出来"<<endl;6311.5文件流11.5.4两种特殊的文件流以文件名"CON"打开的输入文例11-12:

CopyFile接收两个参数:输入文件名和输出文件名,完成从输入文件和输出文件的拷贝6411.5文件流——11.5.4两种特殊的文件流例11-12:CopyFile接收两个参数:输入文件名和输例11-12(续)//CopyFile.h#include<iostream>#include<fstream>usingnamespacestd;voidCopyFile(constchar*from,constchar*to);6511.5文件流——11.5.4两种特殊的文件流例11-12(续)//CopyFile.h6511.5文件例11-12(续)//CopyFile.cpp#include"CopyFile.h"voidCopyFile(constchar*from,constchar*to){ cin.clear(); ifstreaminf(from); if(!inf){ cerr<<"输入文件打开失败!"<<endl; exit(1); } ofstreamoutf(to,ios_base::trunc); if(!outf){ cerr<<"输出文件打开失败!"<<endl; exit(3); } while(!inf.eof())outf.put(inf.get()); inf.close(); outf.close();}6611.5文件流——11.5.4两种特殊的文件流例11-12(续)//CopyFile.cpp6611.5例11-12(续)//11-12.cpp#include"CopyFile.h"

intmain(){ charfin[30],fout[30]; cout<<"输入文件:";cin>>fin; cout<<"输出文件:";cin>>fout; CopyFile(fin,fout);

return0;}6711.5文件流——11.5.4两种特殊的文件流例11-12(续)//11-12.cpp6711.5文件流运行结果:输入文件:copyfile.h输出文件:con//CopyFile.h#include<iostream>#include<fstream>usingnamespacestd;voidCopy(constchar*from,constchar*to);例11-12(续)11.5文件流——11.5.4两种特殊的文件流68运行结果:例11-12(续)11.5文件流——11.5.411.6.1字符串流的建立字符串流以内存中的一个字符串缓冲区为输入/输出对象。istringstream是字符串输入流类,ostringstream是字符串输出流类,stringstream是字符串输入/输出流类。字符串流有一个需要两个参数的构造函数,第一个通过一个字符串为缓冲区提供初始数据,第二个用于指定打开模式。对应于ostringstream、istringstream和stringstream这三种不同的字符串流,第二个参数的默认值分别是:ios_base::out、ios_base::in和ios_base::out

|

ios_base::in。6911.6字符串流11.6.1字符串流的建立字符串流以内存中的一个字符串缓冲区11.6.1字符串流的建立(续)字符串流还有一个只需要一个参数的构造函数,该参数与前述构造函数的第二个构造函数相同,用于指定打开模式,也有默认值。下面是创建字符流的几个例子:ostringstreamost1(“Thisisastring”,ios_base::app);ostringstreamost2;istringstreamist1(“Thisisastring”);istringstreamist2;stringstreamst;7011.6字符串流11.6.1字符串流的建立(续)字符串流还有一个只需要一个参11.6.2字符串流的缓冲区操作字符串流除了可以用rdbuf函数访问和设置缓冲区外,还有一个更方便的str函数,它把缓冲区中的数据视为一个字符串:stringstr()const;

返回缓冲区中的字符串voidstr(conststring&str);

设置缓冲区中的字符串7111.6字符串流11.6.2字符串流的缓冲区操作字符串流除了可以用rdbu例11-13:函数wordPicker提取输入流中的每个词,并按原来的顺序显示输出,但用逗号作为词之间的分隔符7211.6字符串流——11.6.2字符串流的缓冲区操作例11-13:函数wordPicker提取输入流中的每个词,#include<iostream>#include<sstream>usingnamespacestd;

voidwordPicker(istream&is){ stringword; while(is>>word)cout<<word<<','; cout<<endl;}intmain(){ istringstreamsrc("Thisisastring"); wordPicker(src); src.clear(); //清除“eof”,将状态置为“good” src.str(“Thisisanotherstring”);//用参数字符串替换缓冲区 wordPicker(src);cout<<“Keyinsomewords:”; wordPicker(cin);cout<<endl; return0;}7311.6字符串流——11.6.2字符串流的缓冲区操作例11-13(续)#include<iostream>7311.6字符串流—运行结果:This,is,a,string,This,is,another,string,Keyinsomewords:ThisisthethirdstringThis,is,the,third,string,^Z例11-13(续)11.6字符串流——11.6.2字符串流的缓冲区操作74运行结果:例11-13(续)11.6字符串流——11.6.11.7针对自定义类型重载>>和<<可以针对自定义类型重载提取运算符>>和插入运算符<<,单只可能作为全局函数重载。重载这两个运算符函数须使用如下原形:istream&operator>>(istream&is,<类名>&obj);

ostream&operator<<(ostream&os,<类名>obj);其中ostream的第二个参数也可以是const<类名>&obj。7511.7针对自定义类型重载>>和<<可以针对自定义类型重载例11-14:对自定义类DoubleArray重载>>和<<,用以完成数组的输入和输出7611.7针对自定义类型重载例11-14:对自定义类DoubleArray重载>>和<<//DoubleArray.h#include<iostream>usingnamespacestd;

classDoubleArray{ intmin_index; intmax_index; double*data;public: DoubleArray(intmin,intmax); DoubleArray(intmax); DoubleArray(){delete[]data;}; double&operator[](intindex)const; intgetMinIndex()const{returnmin_index;} intgetMaxIndex()const{returnmax_index;}};

istream&operator>>(istream&is,DoubleArray&a);ostream&operator<<(ostream&os,constDoubleArray&a);7711.7针对自定义类型重载例11-14(续)//DoubleArray.h7711.7针对自定义类型重//DoubleArray.cpp#include"DoubleArray.h"DoubleArray::DoubleArray(intmin,intmax):min_index(min),max_index(max){if(min>max){//若下标范围的下界大于上界,显示出错信息并退出 cout<<"Errorindexrange"; exit(1);}data=newdouble[max_index-min_index+1];}

DoubleArray::DoubleArray(intmax):min_index(0),max_index(max){ data=newdouble[max_index+1];}7811.7针对自定义类型重载例11-14(续)//DoubleArray.cpp7811.7针对自定义类double&DoubleArray::operator[](intindex)const{ if(index<min_index||index>max_index){//若下标越界,显示出错信息并退出 cout<<"Indexoutofrange"; exit(1); } returndata[index-min_index];}

istream&operator>>(istream&is,DoubleArray&a){ for(inti=a.getMinIndex();i<=a.getMaxIndex();i++) is>>a[i]; returnis;}

ostream&operator<<(ostream&os,constDoubleArray&a){ for(inti=a.getMinIndex();i<=a.getMaxIndex();i++)os<<a[i]<<''; returnos;}7911.7针对自定义类型重载例11-14(续)double&DoubleArray::operator例11-14(续)//11-14.cpp#include"DoubleArray.h"intmain(){ DoubleArrayx(3,8); cout<<"请输入"<<(x.getMaxIndex()-x.getMinIndex()+1)<<"个数据:"; cin>>x; cout<<"刚输入的数据是:"; cout<<x<<endl;

return0;}8011.7针对自定义类型重载例11-14(续)//11-14.cpp8011.7针对自运行结果:请输入6个数据:123456刚输入的数据是:123456例11-14(续)11.7针对自定义类型重载81运行结果:例11-14(续)11.7针对自定义类型重载81小结本章我们主要学习了如何使用流进行输入/输出。首先介绍了流的基本概念,其次讲述了无格式和有格式的输入/输出方法和注意事项,然后介绍了流在文家输入/输出中的应用和字符串流,最后介绍了插入运算符<<和提取运算符>>在自定义类型中的重载。82小结本章我们主要学习了如何使用流进行输入/输出。首先介绍了流第十一章

输入/输出流第十一章输入/输出流学习目标掌握C++输入/输出流(I/O流)的基本概念;能够在输入/输出中进行基本的格式控制;掌握文件的I/O操作。84学习目标掌握C++输入/输出流(I/O流)的基本概念;2目录11.1C++输入输出流的概念11.1.1什么是输入输出流11.1.2流类库的头文件11.1.3预定义流对象11.1.4I/O流库的类体系11.1.5输出流举例11.1.6输入流举例85目录11.1C++输入输出流的概念3目录(续)11.2无格式的输入/输出11.2.1无格式输入11.2.2无格式输出11.3有格式的输入/输出11.3.1默认的输入/输出格式11.3.2格式标志的设置11.3.3格式控制操纵符11.4I/O流的状态86目录(续)11.2无格式的输入/输出4目录(续)11.5文件流11.5.1文件的概念11.5.2文件流的建立11.5.3文件流的关闭11.5.4两种特殊的文件流11.6字符串流11.6.1字符串流的建立11.6.2字符串流的缓冲区操作11.7针对自定义类型重载>>和<<87目录(续)11.5文件流511.1.1什么是输入/输出流C++将数据从一个对象到另一个对象的流动抽象为“流”。在程序中,“流”具体体现为一个对象,负责在数据生产者和数据消费者之间建立联系,控制数据的流动。例如cin、cout就是两个流对象。利用I/O流既可进行有格式输入/输出,也可进行无格式输入/输出。为了实现格式化的输出,I/O流类库提供了丰富的流操纵符,比如设置输出域的宽度,设置输出精度,设置填充字符等。8811.1

C++输入输出流的概念11.1.1什么是输入/输出流C++将数据从一个对象到另一11.1.2流类库的头文件<iostream>:

包括istream、ostream、iostream以及cin、cout、ceer和clog对象的定义,同时提供非格式化和格式化的I/O服务。针对标准设备的I/O操作,须包含之。<sstream>:

包括istringstream、ostringstream、stringstream的定义,要使用字符串流对象进行针对内存字符串空间的I/O操作,须包含此文件。<fstream>:

包括ifstream、ofstream、fstream的定义,要使用文件流对象进行针对磁盘文件的I/O操作,须包含此文件。<iomanip>:

包括setw、fixed等等操纵符的定义,利用操纵符进行格式化I/O操作,须包含之。8911.1

C++输入输出流的概念11.1.2流类库的头文件<iostream>: 711.11.1.3预定义流对象C++中一共有4个预定义流对象,它们的名称及与之联系的I/O设备如下:cin 标准输入流对象,对应标准输入设备

cout 标准输出流对象,对应标准输出设备

cerr 标准错误信息输出流对象,对应标准出错信息输出设备

clog 标准错误信息输出流对象,对应带缓冲的标准出错信息输出设备这里提到的标准输入设备和标准输出设备是操作系统下的两种虚拟设备,每种虚拟设备都与一种具体的设备相连接。通常情况下,标准输入设备与键盘相连接,标准输出设备与显示器相连接,但可以重定向为与其他设备(如磁盘)。在程序中可以定义自己的流对象(称为自定义流对象),以满足特定输入、输出需求。9011.1

C++输入输出流的概念11.1.3预定义流对象C++中一共有4个预定义流对象,它11.1.4I/O流库的类体系I/O流库的类体系C++通过一系列的流类将不同类型数据的输入/输出操作封装起来,以面向对象的方式规范各种输入/输出操作,提供了一套简化的操作界面,使得不同类型的数据的输入/输出可以采用相同的语法格式。部分流类之间的继承关系如图。9111.1

C++输入输出流的概念11.1.4I/O流库的类体系I/O流库的类体系911.111.1.5输出流举例一个输出流对象是信息流动的目标,最重要的三个输出流是ostream、ostringstream和ofstream。ostream是通用输出流类,cout、cerr和clog都是它的对象;ostringstream是字符串输出流类,它将一片内存空间作为输出设备;ofstream是文件输出流类。9211.1

C++输入输出流的概念11.1.5输出流举例一个输出流对象是信息流动的目标,最重例11-1:向标准设备输出字符串#include<iostream>usingnamespacestd;intmain(){

char*word="helloworld!";

doublepi=3.1415926;

温馨提示

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

评论

0/150

提交评论