-
C++语言不直接处理输入输出,而是通过一族定义在标准库中的类型来处理IO
iostream
定义了用于读写流的基本类型fstream
定义了读写命名文件的类型sstream
定义了读写内存string
对象的类型
-
标准库使得我们能够忽略这些不同类型的流之间的差异,是通过继承机制实现的
-
不能拷贝或者对IO对象赋值,因此也不能将形式参数或者返回类型设置为流类型,进行IO操作的函数通常是已引用方式传递和返回流,读写一个IO对象会改变其状态,因此传递和返回的引用不能是
const
的strm::iostate 提供表达条件状态的完整功能 strm::badbit 用来指出流已经崩溃 strm::failbit 用来指出一个IO操作失败了 strm::eofbit 用来指出流到达了文件结束 strm::goodbit 用来指出流未处于错误状态,此值保证为零 s.eof() 若流s的eofbit置位,返回true s.fail() s.bad() s.good() 若流s处于有效状态,返回true s.clear() 所有条件状态复位,将流的状态设置为有效,返回void s.clear(flags) 根据给定的flags标志位将流s中对应条件状态位复位 s.setstate(flags)同上 s.rdstate() 返回流s的当前条件状态
auto old_state = cin.rdstate(); //记住cin的当前状态 cin.clear() //使cin有效 process_input(cin); //使用cin cin.setstate(old_state); //将cin置为原有状态 cin.clear(cin.rdstate & ~cin.failbit & ~cin.badbit); //复位failbit和badbit,保持eofbit不变
-
通过缓冲机制,操作系统可以将程序的多个输出操作组合成单一的系统级写操作。(原因在于设备的写操作可能很耗时)
-
导致缓冲刷新的原因:
- 程序正常结束,作为
main
函数的return
操作的一部分,缓冲刷新被执行 - 缓冲区满
- 使用操纵符
endl
显式刷新缓冲区 - 在每个输出操作后,可以用操作符
unitbuf
设置流的内部状态,来清空缓冲区(默认情况下cerr
是设置unitbuf
的,因此写到cerr
的内容都是立即刷新的) - 一个输出流可能被关联到另一个流。在这种情况下,当读写被关联的流时,关联到的流的缓冲区会被刷新
- 程序正常结束,作为
-
除了
endl
外,还可以使用flush
和ends
刷新缓冲区,但是他们有不同的效果:cout << "hi" << endl; //输出"hi\n" cout << "hi" << flush; //输出"hi" cout << "hi" << ends; //输出"hi "
-
如果想在每次输出操作后都刷新缓冲区,我们可以使用
unitbuf
操纵符,它告诉流在接下来每次写操作后都进行一次flush
操作cout << unitbuf; //所有输出操作都会立即刷新缓冲区 cout << nounitbuf; //回到正常的缓冲方式
-
调试/程序崩溃时要记得及时刷新缓冲区
-
当一个输入流被关联到一个输出流时,任何试图从输入流读取数据的操作都会先刷新关联的输出流(例如
cin
和cout
)。交互式系统通常应该关联输入流和输出流。每个输入流最多关联到一个流,但多个流可以同时关联到同一个ostream
cin.tie(); //返回cin关联的流,如果之前没有关联则返回空指针 cin.tie(&cout); //返回值同上,但是将cin与cout关联 ostream *old_tie = cin.tie(nullptr); //取消关联,同时保存关联的流的指针 cin.tie(old_tie); //恢复关联
-
文件输入输出的流定义在头文件
fstream
中fstream fstrm; fstream fstrm(s); 打开名为s的文件,s可以是string类型或者是一个指向C风格字符串的指针,默认的文件模式mode依赖 fstream的类型 fstream fstrm(s, mode); fstrm.open(s); 打开名为s的文件,并将文件与fstrm绑定,返回void fstrm.close(); 关闭与fstrm绑定的文件,返回void fstrm.is_open(s); 返回一个bool,指出与fstrm关联的文件是否打开成功且尚未关闭
-
我们可以用
fstream
代替iostream&
,即在需要接受一个iostream
类型引用或者指针参数的函数可以用一个对应的fstream
或sstream
来调用 -
在使用流之前检查是一个好的习惯
-
当一个
fstream
对象被销毁时,close
会自动被调用 -
每个流都有一个关联的文件模式,用来指出如何使用文件
in 以读方式打开,只可以对ifstream或fstream out 以写方式打开,只可以对ofstream或fstream,默认情况下,即使我们没有指定trunc,以out模式打开的文件也会被截 断,为了保留以out模式打开的文件的内容,我们必须同时指定app,或者指定in fstream默认关联in和out app 每次操作均定位到文件末尾,只要trunc没有被设定就可以设定,包含out ate 打开文件后立即定位到文件末尾 trunc 截断文件,只有当out也被设定时才能设定 binary 以二进制方式进行IO
//下面三种方式打开文件是等价的,都会截断文件 ofstream out("file"); ofstream out("file", ofstream::out); ofstream out("file", ofstream::out | ofstream::trunc); //为了保留文件的内容,我们必须显式指定app模式 ofstream out("file", ofstream::app); ofstream out("file", ofstream::out | ofstream::app);
-
sstream
头文件定义了三个类型来支持内存IO,这些类型可以向string
写入数据,从string
读取数据 -
istringstream
从string
读取数据,ostringstream
向string
写入数据,stringstream
既可以读也可以写sstream strm; sstream strm(s); strm保存string类型的s的拷贝 strm.str() 返回strm保存的string的拷贝 strm.str(s) 将string s拷贝到strm中,返回void
C++Primer学习笔记:第8章 IO库
最新推荐文章于 2022-07-11 18:08:16 发布