6、C++ Primer 4th 笔记,标准IO库(1)
1、如果两种类型存在继承关系,则可以说一个类“继承”了其父类的行为-接口。IO 类型在三个独立的头文件中定义:iostream 定义读写控制窗口的类型,
fstream 定义读写已命名文件的类型,而 sstream 所定义的类型则用于读写存
储在内存中的 string 对象。
2、如果函数有基类类型的引用形参,可以给函数传递其派生类型的对象。
3、支持wchar_t类型的类前面加一个w前辍,以此与char类型的版本区分。
4、出于某些原因,标准库类型不允许做复制或赋值操作。两层含义:(1)只有支持复制的元素类型可以存储在vector或其它容器类型里;(2)形参或返回类型也不能为流类型,如果需要传递或返回IO对象,则必须传递或返回指向该对象的指针或引用。
一般情况下,如果要传递IO对象以便对它进行读写,可以用非const引用的方式传递这个流对象。
5、条件状态
IO 标准库管理一系列条件状态(condition state)成员,用来标记给定的IO 对象是否处于可用状态,或者碰到了哪种特定的错误。如下表所示,还定义了三种iostate类型的常量值,分别表示特定的位模式,可以与位操作符一起使用。
strm::iostate |
机器相关的整型名,由各个iostream类定义,用于定义条件状态 |
strm::badbit |
strm::iostate 类型的值,用于指出被破坏的流 |
strm::failbit |
strm::iostate 类型的值,用于指出失败的IO操作 |
strm::eofbit |
strm::iostate 类型的值,用于指出流已经到达文件结束符 |
s.eof() |
如果设置了流 s 的 eofbit 值,则该函数返回true |
s.fail() |
如果设置了流 s 的 failbit 值,则该函数返回true |
s.bad() |
如果设置了流 s 的 badbit 值,则该函数返回 true |
s.good() |
如果流 s 处于有效状态,则该函数返回 true |
s.clear() |
将流 s 中的所有状态值都重设为有效状态 |
s.clear(flag) |
将流s中的某个指定条件状态设置为有效。flag的类型是strm::iostate |
s.setstate(flag) |
给流 s 添加指定条件。flag 的类型是 strm::iostate |
s.rdstate() |
返回流 s 的当前条件,返回值类型为 strm::iostate |
流必须处于无错误状态才能用于输入输出。
所有的流对象都包含一个条件状态成员,该成员由setstate和clear操作管理。这个状态成员为iostate类型,这是由各个iostream类分别定义的和机器相关的整形。该状态成员以二进制位bit的形式使用。
badbit 标志着系统级的故障,如无法恢复的读写错误。如果出现了这类错误,则该流通常就不能再继续使用了。
如果出现的是可恢复的错误,如在希望获得数值型数据时输入了字符,此时则设置failbit标志,这种导致设置failbit的问题通常是可以修正的。
eofbit是在遇到文件结束符时设置的,此时同时还设置了failbit。
流的状态由bad、fail、eof和good操作提示。如果bad、fail或者eof中的任意一个为true,则检查流本身将显示该流处于错误状态。类似地,如果这三个条件没有一个为true,则good操作将返回true。
使用示例:查询和控制
int ival; // read cin and test only for EOF; loop is executed even if there are other IO failures while (cin >> ival, !cin.eof()) { if (cin.bad()) // input stream is corrupted; bail out throw runtime_error("IO stream corrupted"); if (cin.fail()) { // bad input cerr<< "bad data, try again"; // warn the user cin.clear(istream::failbit); // reset the stream continue; // get next input } // ok to process ival }
使用示例:访问条件状态
// remember current state of cin istream::iostate old_state = cin.rdstate(); cin.clear(); process_input(); // use cin cin.clear(old_state); // now reset cin to old state
多个状态位可以用按位与(AND)或按位或操作(OR)来一起设置。
is.setstate(ifstream::badbit | ifstream::failbit);
6、输出缓冲区的管理
每个IO对象管理一个缓冲区,用于存储程序读写的数据。以下几种情况导致缓冲区的内容被刷新:
(1)程序正常结束。作为 main 返回工作的一部分,将清空所有输出缓冲区。
(2)在一些不确定的时候,缓冲区可能已经满了,在这种情况下,缓冲区将会在写下一个值之前刷新。
(3)用操纵符显式地刷新缓冲区,例如行结束符 endl。
endl:用于输出一个换行符并刷新缓冲区;
ends:在缓冲区中插入空字符NULL,然后刷新它;
flush:刷新流。
(4)在每次输出操作执行完后,用 unitbuf 操作符设置流的内部状态,从而清空缓冲区。
如果需要刷新所有输出,用nuitbuf操作符。这个操作符在每次写操作后都刷新流。
cout << unitbuf << "first" << " second" << nounitbuf; 等价于: cout << "first" << flush << " second" << flush;
nounitbuf 操纵符将流恢复为使用正常的、由系统管理的缓冲区刷新方式。
(5)可将输出流与输入流关联(tie)起来。在这种情况下,在读输入流时将刷新其关联的输出缓冲区。
标准库将cout与cin绑在一起。交互式系统通常应确保它们的输入输出流是绑在一起的。
tie 函数可用 istream 或 ostream 对象调用,使用一个指向 ostream 对象的指针形参。调用 tie 函数时,将实参流绑在调用该函数的对象上。如果一个流调用 tie 函数将其本身绑在传递给 tie 的 ostream 实参对象上,则该流上的任何 IO 操作都会刷新实参所关联的缓冲区。
绑定示例
一个ostream对象每次只能与一个istream对象绑在一起,如果调用tie函数时传递实参0,则To break an existing tie。
cin.tie(&cout); // illustration only: the library ties cin and cout for us ostream *old_tie = cin.tie(); cin.tie(0); // break tie to cout, cout no longer flushed when cin is read cin.tie(old_tie); // restablish normal tie between cin and cout
参考:
[1] http://blog.163.com/zhoumhan_0351/blog/static/39954227201002945157577/
[2] http://blog.163.com/zhoumhan_0351/blog/static/39954227201003005237697/
[3] http://blog.163.com/zhoumhan_0351/blog/static/399542272010030103055465/
[4] http://blog.163.com/zhoumhan_0351/blog/static/39954227201002192139554/
[5] http://blog.163.com/zhoumhan_0351/blog/static/3995422720103171303182/