C++基础--输入输出流类

 
C++基础--输入输出流类
1 输入输出流类层次
  iostream是一组C++类,用于实现面向对象模型的输入输出,可以提供无缓冲的(低级)和缓冲的I/O操作。在某些情况下,如果C++编译器提供的iostream库中没有合适的输入输出函数可用,我们还可以利用类的继承和多态特性来改进它们,左图给出了I/O流类之间的继承关系。
图12-1 I/O流类层次图

抽象流基类
ios         流基类
输入流类
istream       普通输入流类和用于其它输入流的基类
ifstream      输入文件流类
istream_withassign 用于cin的输入流类
istrstream     输入串流类
输出流类
ostream      普通输出流类和用于其它输出流类的基类
ofstream      输出文件流类
ostream_withassign 用于cout、cerr和clog的流类
ostrstream.    输出串流类
输入输出流类
iostream      普通输入输出流类和用于其它输入输出流的基类
fstream      输入输出文件流类
strstream     输入输出串流类
stdiostream    用于标准输入输出文件的输入输出类
缓冲流类
streambuf     抽象缓冲流基类
filebuf      用于磁盘文件的缓冲流类
strstreambuf.   用于串的缓冲流类
stdiobuf      用于标准输入输出文件的缓冲流类
预定义流初始化类
iostream_init   预定义流初始化的类
  其中,ios、istream、ostream和streambuf类构成了C++中iostream输入输出功能的基础。
在图中,streambuf类和ios类没有继承关系,它们是组合使用的,streambuf对象作为ios类的成员出现。事实上,ios类提供编程界面和格式特征,而streambuf做实质性的工作。
  iostream类库中,streambuf、ios、istream、ostream、iostream、istream_withassign和ostream_withassign这些基本I/O流类和预定义的cin、cout、cerr和clog在iostream.h文件中说明。
  filebuf、ifstream、ofstream和fstream在fstream.h中说明。
  strstream、istrstream、ostrstream和strstream在strstrea.h中说明。
  需要注意的是:fstream.h和strstrea.h中都包含了iostream.h,所以如果使用标准输入输出(控制台I/O),只要包含iostream.h头文件即可,如果使用fstream或者strstream,只要包含相应的fstream.h和strstrea.h即可。
2标准输入和输出
  输出流类在iostream.h中预定义了四个全局的流对象:cout、cerr、clog和cin,用于标准输出和输入,cout和cin在程序设计中会经常用到。
  cout流对象控制向控制台(显示器)的标准输出,cin控制从控制台(键盘)输入。cerr与标准错误设备连在一起,是非缓冲输出,也就是说插入到cerr的数据会被立刻显示出来,非缓冲输出可以迅速把出错信息告知用户。clog也是与标准错误设备连在一起的,但它是缓冲输出。
一、标准输出
  程序12-1中出现了<<运算符,它是C++中的逐位左移运算符。不过,此运算符在这里被重载,用于流输出操作,称之为插入运算符。它不仅完成逐位左移,而且还能够将对象插入到数据流中,而数据流可以连接到任何与计算机相连的输出设备。cout对象是与控制台相连的,当对象插入到cout中时,它们被发送到控制台(监视器)。例如程序12-1完成的是向控制台输出"pi=3.14159"。同样,其它内部数据类型也可以插入到数据流中。因为<<运算符返回的是ostream对象的引用,所以程序12-1可以简化成:
  cout<<"pi="<<pi;
这样可以使程序更加简洁易懂。
  引入了插入运算符<<,使ostream类具有了通用性和设备无关性,这是通过多态来实现的。用户可以通过重载插入运算符,将自定义的数据类型进行翻译转换,插入到数据流中,这在后面要详细介绍。
  应用<<运算符,执行格式化插入到ostream类中的对象并不象它们原来那样发送到输出,而是首先被转换成简单的数据类型(字节流)。但是在许多情况下,我们希望将数据直接插入到流中而不进行转换。为此ostream类提供了两个函数:put()和write()。前者是将一个字符、无符号字符或者有符号字符插入到字节流中;后者用于插入一个字符数组到字节流中,但不进行任何转换,用于将非格式化的二进制组写到文件和输出设备中。
  程序12-2将字符'A'和一组代表非格式float值的字节1.4(4个字节)直接显示到控制台上,显示到控制台的结果实际上是一堆乱码。
二、标准输入
  程序12-5出现了>>运算符,它是C++中的逐位右移运算符。不过,此运算符在这里也被重载,用于流输入操作,称之为抽取运算符。它不仅完成逐位右移,而且还能够从数据流中抽取数据对象。而数据流可以连接到任何与计算机相连的输入设备,cin是与控制台输入相连。当控制台输入数据时,cin中生成数据并保存到相应变量中,如程序12-5所示。由于>>操作符返回的是istream对象的引用,所以程序12-5可以简化成:
  cin>>n>>ch>>pi>>str;
  这里有一个问题。在程序12-5中,当输入"5 c 3.14159 hello world!"时,运行结果并不是我们所期望的:
  n=5
  ch=c
  pi=3.14159
  string=hello world!
  而是:
  i=5
  ch=c
  pi=3.14159
  string=hello
  str只得到第一个字"hello",而不是"hello world!",这是由于输入机制是通过寻找空格来分隔输入的,而空格在"hello"的后面,所以"world!"被截掉了。要解决这个问题,可以使用非格式化抽取的方法

istream有三个从流中进行非格式化抽取的成员函数:get()、getline()和read()。
  流输入的抽取过程由于类型不匹配等原因,有可能会出现错误,当一步抽取出现错误,以后各步的抽取过程也是错误的。所以在抽取数据期间测试错误也是很重要的,我们将在后面单独进行介绍。

表12-1 成员函数get()的用法
int get()从流中抽取单个字符并返回。
istream& get(char*,int,char) 从流中抽取字符直到终止符(缺省为'/n')或者抽取字符达到第二个参数给定的数量或者已到文件尾,将其存储在第一个参数指定的字符数组里。
istream& get(char &)从流中抽取单个字符并存入引用变量中
istream& get(streambuf &,char)从流中取得字符存入streambuf对象,直到终止符或文件尾
  get()在上述任何情况下,都不从流中提取终止符。
表格表12-2 成员函数getline()的用法
istream& getline(char*,int,char) 从流中抽取字符直到终止符(缺省为'/n'),或者抽取字符达到参数给定的数量-1,或者已到文件尾,将其存储在第一个参数指定的字符数组里。如果发现终止符,它从流中提取终止符,但只是抛弃掉,并不把它存在结果缓冲区里。
表格表12-3 成员函数read()的用法
istream& read(char*,int) 从流中抽取字节直到参数给定的数量或者到文件结束,将其存储在第一个参数指定的字符数组里。该函数用于二进制输入流。

3 操纵算子
  操纵算子是插入到流中或从流中抽取出来、影响流的格式状态的函数或对象。流的格式状态由ios类定义,其中包括指定数据对象的基数,如十进制、八进制、十六进制等,还有输出宽度、精度、填充字符等等。事实上,ios类有自己的成员函数可以设置、清除这些格式变量。操纵算子与这些成员函数的功能是重叠的,但是引入操纵算子为我们提供了很大的方便和表达能力,它们有助于提高程序的可读性。
  表12-4列出了I/O流类预定义的操纵算子,其中的无参数操纵算子在iostream.h中定义,在使用时应包含该头文件。另外,在使用带参数操纵算子时,应包含iomanip.h头文件,这个文件中包含了解决建立带参数操纵算子遇到的一般问题的代码。

表12-4 操纵算子清单
操纵算子作用
endl输出换行符并刷新流
ends输出空字符
flush刷新流
dec将数值转化为十进制
hex将数值转化为十六进制
oct将数值转化为八进制
ws跳过空白字符(用于输入)
setiosflags(fmtflags n)设置由n指定的格式标志;设置一直起作用直到下一个变化为止,作用同ios::setf()。格式标志在ios类中定义,参见表12-5。
setbase(base n)把基数改成n,这里n取10、8或16(任何别的值结果为0)。如果n是0,输出基数为10,但输入使用c语言的约定: 10是10,010是8而0xf是15。推荐使用dec、oct和hex
setfill(char n)把填充字符改成n,作用同ios::fill()
setprecision(int n)把精度改成n,作用同ios::precision()
setw(int n)把域宽改成n,作用同ios::width(),只影响它后面的要输出的数据,当这个数据打印完毕后,域宽恢复到缺省状态
表格表12-5 格式标志清单
showbase在打印一整数值时,标明数字基数(十进制,八进制和十六进制);所用的格式能被c + +编译器读出
noshowbase
showpos显示正值符号加(+)
noshowpos
uppercase显示代表十六进制值的大写字母a - f以及科学记数法中的e
nouppercase
showpoint表明浮点数值的小数点和后面的零
skipws跳过输入中的空白字符
noskipws
left左对齐,右填充
right右对齐,左填充
internal在引导符或基数指示符和值之间填充
scientific使用科学记数法
fixedsetprecision()或ios::precision()设置小数点后面的位数

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值