新的C++标准中有三分之二的内容都是描述标准库。接下来重点学习其中几种核心库设施,这些是应该熟练掌握的。

  标准库的核心是很多容器类(顺序容器和关联容器等)和一簇泛型算法(该类算法通常在顺序容器一定范围内的元素上或其他类型的序列上进行操作)。

  该篇主要学习IO库。

  C++语言不直接处理输入输出,而是通过一簇标准库中的IO库来处理。IO库定义了读写内置类型值的操作。

1、IO类

  为了处理不同的种类的IO操作,定义了:iostream(用于读写流的基本类型)、fstream(读写命名文件的类型)、sstream(读写内存string对象的类型)。

其中后面以w开头的是宽字符版本。

IO类型间的关系

继承机制:ifstream和istringstream都是继承自istream,上述所有的IO库类型之间都存在这种继承关系。

下面介绍的标准库流特性都可以无差别地应用于普通流、文件流和string流,以及它们的宽字符版本。

1.1 IO对象无拷贝或赋值

不能拷贝或对IO对象赋值

ofstream out1,out2;
out1=out2; //错误,不能对流对象赋值
ofstream print(ofstream); //错误,不能初始化ofstream参数
out2=print(out2); //错误,不能拷贝流对象

因为不能拷贝IO对象,因此不能将形参或返回类型设置为流类型。进行IO操作的函数通常以引用方式传递和返回流。读写一个IO对象会改变其状态,因此传递和返回的引用不能是const。

1.2 条件状态

IO操作可能会发生错误,IO类通过定义一些条件状态来显示IO对象的状态,使用户知道流的当前状态。

由于流操作可能发生的错误,因此,代码通常应该在使用一个流之前检查它是否处于良好状态,最简单的方法是将它当作一个条件来使用。

while(cin>>word)
{
......
}

查询流的状态

有时候不仅仅需要知道流是否有效,还要知道到底是什么原因导致流失效,IO库定义了一个与机器无关的iostate类型,它提供了表达流状态的完整功能。这个类型应作为一个位集合来使用。

使用good或fail是确定流的总体状态的正确方法。上述将流作为条件使用的代码等价于!fail()。

while(cin>>word)
{
......
} ================== cin >> s;
while (!(cin.fail()))
{ }

管理条件状态

流对象的rdstate成员返回一个iostate值,对应流的当前状态。setstate操作将给定条件位置位,表示发生了对应错误。clear成员是一个重载的成员。有一个无参数的版本,清除所有错误标志位。

auto old_state=cin.rdstate();    //记住cin的当前状态
cin.clear(); //清除所有错误
process_input(cin); //使用cin
cin.setstate(old_state); //将cin置为原有状态

1.3 管理输出缓冲

每个输出流都管理一个缓冲区,用来保存程序读写的数据。

刷新输出缓冲区

已经使用过操纵符endl,它完成换行并刷新缓冲区的工作。IO库还有两个类似的操纵符:flush和ends。flush刷新缓冲区,但不输出任何额外的字符;ends向缓冲区插入一个空字符,然后刷新缓冲区。

unitbuf操纵符

unitbuf每次输出操作后都刷新缓冲区。它告诉流在接下来的每次写操作之后都进行一次flush。而nounitbuf操纵符则重置流,使其恢复正常的系统管理的缓冲区刷新机制。

cout<<unitbuf;    //所有输出操作后都会立即刷新缓冲区

cout<<nounitbuf;    //回到正常的缓冲方式

2、文件输入输出

头文件fstream定义了三种类型来支持文件IO:ifstream、ofstream、fstream。

fstream除了继承自iostream类型的行为之外,fstream还定义了一些自己专有的操作。这是其他IO类型所没有的。

2.1 使用文件流对象

用fstream代替iostream&

在使用iostream的地方,可以用fstream代替调用,因为fstream是从iostream继承来的。

成员函数open和close

可以先定义一个空文件流对象,然后用open将其与文件关联起来。

如果调用open失败,则failbit会被置位,因此进行open是否成功的检测是一个好的习惯。

ofstream out;
out.open("1.txt");
if(out)
.......

将文件流对象绑定到另一个文件之前,需要先close已经关联的文件,然后再关联新的文件。

自动构造和析构

当一个fstream对象被销毁时,close会自动被调用。

2.2 文件模式

每个流都有一个关联的文件模式,用来指出如何使用文件。

指定文件模式有如下限制

  • 只可以对ofstream和fstream对象设定out模式
  • 只可以对ifstream和fstream对象设定in模式
  • 只有当out也被设定时才可设定trunc模式
  • 只要trunc没被设定,就可以设定app模式。在app模式下,即使没有显式指定out模式,文件也总是以输出方式被打开
  • ate和binary模式可用于任何类型的文件流对象,且可以与其他任何文件模式组合使用

每个文件流类型都定义了一个默认的文件模式,ifstream是in,ofstream是out,fstream是in和out

以out模式打开文件会丢弃已有数据

默认情况下,打开一个ofstream时,文件的内容会被丢弃。阻止一个ofstream清空给定文件内容的方法是同时指定app模式。

ofstream app("file",ofstream::app);
ofstream app2("file",ofstream::out | ofstream::app); 

每次调用open时都会确定文件模式

ofstream out;
out.open("file1"); //模式隐含设置为输出和截断
out.close();
out.open("file2",ofstream::app); //模式为输出和追加
out.close();

通常情况下,out模式意味着同时使用trunc模式,因此,file1的文件的内动将被清空。

每次打开文件时,都要设置文件模式,可能是显式地设置,也可能是隐式地设置,当程序未指定模式时,就使用默认值。

3、string流

sstream头文件定义了三个类型来支持内存IO,这些类型可以向string读写数据,string像是一个IO流一样。

  • istringstream
  • ostringstream
  • stringstream

上述三种都继承自iostream。同样的,除了继承来的操作,其也定义了自己特有的操作。

C++系统学习之八:IO库的更多相关文章

  1. 系统学习 Java IO ---- 目录,概览

    Java IO 类的系统教程,原创.主要参考自英文教程 Java IO Tutorial 和 Java Doc. http://tutorials.jenkov.com/java-io/index.h ...

  2. 系统学习 Java IO (一)----输入流和输出流 InputStream/OutputStream

    目录:系统学习 Java IO ---- 目录,概览 InputStream 是Java IO API中所有输入流的父类. 表示有序的字节流,换句话说,可以将 InputStream 中的数据作为有序 ...

  3. 系统学习 Java IO (十六)----这么多类,应该用哪个?

    目录:系统学习 Java IO---- 目录,概览 Java IO目的和功能 Java IO 包含 InputStream,OutputStream,Reader 和 Writer 类的许多子类. 原 ...

  4. 系统学习 Java IO (十四)----字符读写缓存和回退 BufferedReader/BufferedWriter & PushbackReader

    目录:系统学习 Java IO---- 目录,概览 BufferedReader BufferedReader 类构造器接收一个 Reader 对象,为 Reader 实例提供缓冲. 缓冲可以加快 I ...

  5. 系统学习 Java IO (十三)----字符读写 Reader/Writer 及其常用子类

    目录:系统学习 Java IO---- 目录,概览 Reader Reader 类是 Java IO API 中所有 Reader 子类的基类. Reader 类似于 InputStream ,除了它 ...

  6. 系统学习 Java IO (九)----缓冲流 BufferedInputStream/BufferedOutputStream

    目录:系统学习 Java IO---- 目录,概览 BufferedInputStream BufferedInputStream 类为输入流提供缓冲. 缓冲可以加快IO的速度. BufferedIn ...

  7. 系统学习 Java IO (六)----管道流 PipedInputStream/PipedOutputStream

    目录:系统学习 Java IO---- 目录,概览 PipedInputStream 类使得可以作为字节流读取管道的内容. 管道是同一 JVM 内的线程之间的通信通道. 使用两个已连接的管道流时,要为 ...

  8. 系统学习 Java IO (十二)----数据流和对象流

    目录:系统学习 Java IO---- 目录,概览 DataInputStream/DataOutputStream 允许应用程序以与机器无关方式从底层输入流中读取基本 Java 数据类型. 要想使用 ...

  9. 系统学习 Java IO (四)----文件的读写和随机访问 FileInputStream/FileOutputStream & RandomAccessFile

    目录:系统学习 Java IO---- 目录,概览 文件输入流 FileInputStream 这是一个简单的FileInputStream示例: InputStream input = new Fi ...

随机推荐

  1. IT兄弟连 JavaWeb教程 JSP内置对象3

    读取web.xml配置信息的config对象 config对象主要用于取得服务器的配置信息.通过pageContxt对象的getServletConfig()方法获取一个config对象.当一个Ser ...

  2. EasyUI/TopJUI可编辑表格的列根据返回数据判断是使用 combobox 还是 numberbox

    这两天研究了一下topjui的可编辑表格edatagrid,想在每一列的后面根据返回的数据判断是使用 combobox 还是 numberbox,期间遇到了一些坑,下面实现代码,需要的朋友可以参考一下 ...

  3. Log4j2 - 动态生成Appender

    功能需求 项目里将User分成了各个区域(domain),这些domain有个标志domainId,现在要求在打印日志的时候,不仅将所有User的日志都打印到日志文件logs/CNTCore.log中 ...

  4. Tomcat - 怎么控制某个类或者包下的日志打印级别

    问题与分析 Tomcat是使用自己的日志实现tomcat-juli.jar来打印日志信息的,日志会被打印到catalina.out里,除去你在项目里自己使用的日志框架外,由System.out,Sys ...

  5. C# 基础之类与结构体的区别

    1.语法上的区别是: 定义类使用关键字class,定义结构体用关键字struct 2.结构体中不可对声明字段进行初始化,但类可以 3. 类:如果没有为类显示的定义一个构造函数,c#编译器会自动生成一个 ...

  6. 546 Remove Boxes 移除盒子

    给定一些不同颜色的盒子,以不同的正整数表示.消去连续相同颜色的盒子,直到全部消除完毕为止.每一次消去可以得到k * k分(k为消去盒子的个数, k  >= 1).计算可以得到的最大得分.注意:盒 ...

  7. 使用tmodjs

    1.安装 npm install -g tmodjs 2.配置 我的模板都放在tpl文件夹中,htmls用于存放模板页面,每一个后缀名都是.html,而build用于存放编译后输出的模板js. 如果不 ...

  8. Storm编程入门API系列之Storm的Topology多个Workers数目控制实现

    前期博客 Storm编程入门API系列之Storm的Topology默认Workers.默认executors和默认tasks数目 继续编写 StormTopologyMoreWorker.java ...

  9. 关于RegExp的一些使用的练习(代码加注释)

    <!DOCTYPE html> <html> <head> <title>title</title> <meta charset=&q ...

  10. IE浏览器兼容background-size

    background-size是CSS3新增的属性,IE8以下不支持,通过滤镜实现background-size效果 background-size:contain; // 缩小图片来适应元素的尺寸( ...