C++ Primer 笔记——IO类

1.C++语言并未定义任何输入输出语句,取而代之,包含了一个全面的标准库来提供IO机制。

由上图能够知道,I/O操作的基类是ios_base,各个类的用途例如以下:

  • <iostream>
  •                      istream    从流中读取数据
  •                      ostream   向流中写数据
  •                      iostream  对流进行读写操作。派生于istream和ostream
  • <fstream>
  •                      ifstream    从文件里读取数据。派生于istream
  •                      ofstream   向文件里写数据,派生于ostream
  •                      fstream     读写文件, 派生于iostream
  • <sstream>
  •                      istringstream    读取string对象。派生于istream
  •                      ostringstream   写string对象。派生于ostream
  •                      stringstream     读写string对象,派生于iostream

2.C与C++处理输入输出的方式不同,我们从C语言的输入输出可以很明显看出是函数调用方式,而C++的则是对象模式,iostream类是派生于ostream类和istream类,而cout和cin是ostream类和istream类的对象。

3. std::endl 实质上是一个函数,它做了两件事情:输出一个 ' ' 并刷新缓冲区。

// VS2015编译器上的定义    
// MANIPULATORS
template<class _Elem,
    class _Traits> inline
    basic_ostream<_Elem, _Traits>&
        __CLRCALL_OR_CDECL endl(basic_ostream<_Elem, _Traits>& _Ostr)
    {    // insert newline and flush stream
    _Ostr.put(_Ostr.widen('
'));
    _Ostr.flush();
    return (_Ostr);
    }
    // 以下三个语句是等价的
    std::cout << std::endl;
    std::cout << &std::endl;
    std::cout << '
' << std::flush;

4.因为系统在空闲的时候会不停的检查缓冲区,如果发现新内容,将刷新缓冲区,这也是为什么我们不用std::endl或std::flush时也可以正常输出的原因。

5.当从键盘向程序输入数据时,对于如何指出文件结束,不同操作系统有不同的约定。在Windows系统中,输入文件结束符的方法是Ctrl + Z,然后按Enter或Return键。在UNIX系统中,包括Mac OS X系统中,文件结束符输入是用Ctrl+D。

6.由IO对象不能拷贝,所以不能将形参或返回类型设置为流类型,通常以引用的方式传递和返回流,而且不能是const类型。

 

7.IO类定义的一些函数和标志,可以帮助我们访问和操纵流的条件状态。

 

8.一个流一旦发生错误,其上后续的IO操作都会失败,只有当一个流处于无错状态时,我们才可以从它读取或写入数据。

 

9.每个流都管理一个缓冲区,用来保存程序读写的数据,导致缓冲刷新的原因有很多:

  • 程序正常结束
  • 缓冲区满
  • 调用endl或flush或ends(ends向缓冲区插入一个空字符,然后刷新缓冲区。)
  • 每个输出操作之后,我们可以用操作符unitbuf设置流的内部状态,来清空缓冲区。默认情况下,对cerr是设置unitbuf的,因此写到cerr的内容都是立即刷新的。
  • 一个输出流可能被关联到另一个流,当读写被关联的流时,关联到的流的缓冲区会被刷新。例如默认情况下,cin和cerr都关联到cout,因此读cin或写cerr都会导致cout的缓冲区刷新。
std::cout << std::unitbuf;        // 所有输出操作后都会立即刷新缓冲区
std::cout << std::nounitbuf;    // 回到正常的缓冲方式
int i;
std::cin >> i;    // 会导致cout的缓冲区被刷新

10.如果程序异常中止,输出缓冲区是不会被刷新的。当一个程序崩溃后,它所输出的数据很可能停留在输出缓冲区中等待打印。

 

11.我们既可以将一个istream对象关联到另一个ostream,也可以将一个ostream关联到另一个ostream,每个流同时最多关联到一个流,但是多个流可以同时关联到一个ostream。

std::cin.tie(&std::cout);        //标准库将cin和cout关联在一起
std::ostream *old_tie = std::cin.tie(nullptr);    // old_tie指向当前关联到cin的流(如果没有则是空),cin不再与其他流关联
std::cin.tie(&std::cerr);    // 读取cin会刷新cerr而不是cout

文件输入输出

1.除了继承自iostream类型的行为之外,fstream中定义的类型还增加了一些新的成员来管理与流关联的文件。

 

2.创建文件流对象时,如果提供文件名,则open会被自动调用。

 

3.一旦一个文件流已经打开,它就保持与对应文件的关联。对于一个已经打开文件流调用open会失败。当一个fstream对象被销毁时,close会被自动调用。

 

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

默认情况下当我们打开一个ofstream时,文件的内容会被丢失。可以指定app模式避免。而且只要trunc没有被设定,就可以设定app模式。

 

string类

1.sstream中增加了一些成员来管理与流相关的操作。

 

原文地址:https://www.cnblogs.com/zoneofmine/p/7221711.html