iostream头文件定义了用于读写流的基本类型。
fstream头文件定义了读写命名文件的类型。
sstream头文件定义了读写内存string对象的类型。
头文件 | 类型 |
iostream | istream,wistream 从流读取数据 ostream,wostream 向流写入数据 iostream,wiostream 读写流 |
fstream | ifstream,wifstream 从文件读取数据 ofstream,wofstream 向文件写入数据 fstream,wfstream 读写文件 |
sstream | istringstream,wistringstream 从string读取数据 ostringstream,wostringstream 向string写入数据 stringstream,wstringstream 读写string |
为了支持宽字符的语言,标准库定义了以w字母开头的wchar_t类型版本。
继承机制可以将一个派生类(继承类)对象当作其基类(所继承的类)对象来使用。
我们不能拷贝或对IO对象赋值,也不能将形参或返回类型设置为流类型。
进行IO操作的函数通常以引用方式传递和返回流,传递和返回的引用不能是const的。
IO类定义了一些函数和标志来帮助我们访问和操纵流的条件状态。
strm::iostate | 提供表达条件状态的完整功能 |
strm::badbit | 用来指出流已崩溃 |
strm::failbit | 用来指出一个IO操作失败了 |
strm::eofbit | 用来指出流到达了文件结束 |
strm::goodbit | 用来指出流未处于错误状态,此值保证为零 |
s.eof() | 若流s的eofbit置位,则返回true |
s.fail() | 若流s的failbit或eofbit置位,则返回true |
s.bad() | 若流s的badbit置位,则返回true |
s.good() | 若流s处于有效状态,则返回true |
s.clear() | 若流s中的所有条件状态位复位,将流状态设置为有效,返回void |
s.clear(flags) | 将流s中的flags位的条件状态位复位,返回void |
s.ststate(flags) | 将流s中的flags位的条件状态位置位。返回void |
s.rdstate() | 返回流s的当前条件状态 |
置位:把某一位的二进制位设为1; 复位:把某一位的二进制位设为0;
一个流一旦发生错误,其上后续的IO操作都会失败。
badbit被置位表示发生系统性错误,如不可恢复的读写错误。
failbit被置位表示发生可恢复错误,如类型不匹配。
到达文件结束位置,eofbit和failbit都会被置位。goodbit的值为0,表示流未发生错误。
badbit、failbit和eofbit任意一个被置位,则检测状态的条件都会失败。
clear会将所有错误标志位复位。
每个输出流都管理一个缓冲区,用来保存程序读写的数据。
缓冲区帮助操作系统将多个输出操作组合为单一的设备写操作,带来极大的性能提升。
导致缓冲区刷新的常见原因:
1、程序正常结束,main函数的return操作,执行缓冲刷新。
2、缓冲区存储满时,需要刷新缓冲,而后续数据才能继续写入。
3、使用操纵符endl来显式刷新缓冲区。
4、在每个输出操作之后,用操作符unitbuf设置流的内部状态,来清空缓冲区。
5、一个输出流可能被关联到另一个流。当读写到被关联的流,关联到的流的缓冲区刷新。
endl操纵符输出内容并换行,然后刷新缓冲区。
flush操纵符输出内容,然后刷新缓冲区。
ends操纵符输出内容并附加一个空字符,然后刷新缓冲区。
如果想在每次输出操作后都刷新缓冲区,可以使用unitbuf操纵符。
cout << unitbuf;
//任何输出都立即刷新,无缓冲
cout << nounitbuf; //恢复正常的缓冲方式
如果程序异常终止,输出缓冲区是不会被刷新的,数据还存放在原有的位置。
当一个输入流被关联到一个输出流时,任何试图从输入流读取数据的操作都会先刷新输出流。
tie函数接受一个指向ostream的指针,将自己关联到此ostream。
ostream *old_tie = cin.tie(nullptr); //cin不再与其他流关联
cin.tie(&cerr); //cin与cerr关联
cin.tie(old_tie); //cin重新与之前的流关联
向流的参数中传递一个空指针,解开与流关联的其他流。
每个流同时最多关联到一个流,但多个输出流可以同时关联到同一个ostream。
头文件fstream定义了三个类型来支持读写文件:ifstream 读取,ofstream 写入,fstream 读写。
fstream fstrm; | 创建一个未绑定的文件流 |
fstream fstrm(s); | 创建一个fstream,并打开s文件,s类型不会隐式转换 |
fstream fstrm(s,mode); | 与上个函数类似,但按指定mode打开文件 |
fstrm.open(s); | 打开s文件,并将文件与fstrm绑定 |
fstrm.close(); | 关闭与fstrm绑定的文件,返回void |
fstrm.is_open(); | 返回一个bool值,用来判断文件是否成功打开 |
创建文件流对象时,可提供文件名,文件名即可是string对象,也可是C风格字符数组。
ifstream in(文件名);
ofstream out; //输出文件为关联到任何文件
如果我们定义一个空文件流对象,可在随后调用open函数来将它与文件关联。
ofstream out;
out.open(ifile + "copy"); //打开ifile文件,并添加copy
如果调用open失败,failbit会被置位;通常会进行open是否成功的检测。
if(out)
对一个已经打开的文件流调用open会失败,并会导致failbit被置位。
in.close(); //先关闭再打开
in.open(ifile + "2");
当一个fstream对象被销毁时,close会被自动调用。
每个流都有一个关联的文件模式,用来指出如何使用文件。
in | 以读方式打开 |
out | 以写方式打开 |
app | 每次写操作前均定位到文件末尾 |
ate | 打开文件后立即定位到文件末尾 |
trunc | 截断文件 |
binary | 以二进制方式进行IO |
每个文件流类型都定义了默认的文件模式。
与ifstream关联的文件默认以in模式打开;与ofstream关联的文件默认以out模式打开。
默认情况下,当我们打开一个ofstream时,文件的内容会被丢弃。
显式指定app或in模式能保留被ofstream打开的文件中已有数据。
ofstream app("file",ofstream::app);
每次调用open函数时应设置文件模式,否则文件将以out模式隐式地打开。
通常情况下,out模式意味着同时使用trunc模式。
istringstream从string读取数据,ostringstream向string写入数据。
sstream strm; | strm是一个未绑定的stringstream对象 |
sstream strm(s); | strm是一个sstream对象,保存s的一个拷贝。 |
strm.str() | 返回strm所保存的string的拷贝 |
strm.str(s) | 将s拷贝到strm中,返回void |
istringstream常用于处理整行文本中单个元素。
while(getline(cin,line))
{
istringstream record(line); //与一行文本进行绑定
while(record >> word) //读取文本中的单个元素
{
......
}
}