IO 类
iostream |
istream 和 wistream 从流读取数据,ostream 和 wostream
向流写入数据,iostream 和 wiostream 读写流 |
fstream |
ifstream 和 wifstream 从流读取数据,ofstream 和 wofstream
向流写入数据,fstream 和 wfstream 读写流 |
sstream |
istringstream 和 wistringstream 从 string 读取数据,ostringstream 和
wostringstream 向 string 写入数据,stringstream 和 wstringstream 读写
string |
条件状态
strm::iostate |
strm 是一种 IO 类,提供了表达流状态的完整功能 |
strm::badbit |
用于指出流已崩溃 |
strm::failbit |
用于指出一个 IO 操作失败 |
strm::eofbit |
用于指出流到达了文件结束 |
strm::goodbit |
用于指出流未处于错误状态, |
s.eof() |
若流 s 的 eofbit 置位,则返回 true |
s.fail() |
若流 s 的 fail 或 badbit 置位,则返回 true |
s.bad() |
若流 s 的 badbit 置位,则返回 true |
s.good() |
若流 s 处于有效状态,则返回 true |
s.clear() |
若流 s 中所有条件状态位复位,将流的状态位置设置为有效,返回
void |
s.clear(flags) |
根据给定的 flags 标志位,将流 s 中对应条件状态位复位,flags 的类型为
strm::iostate,返回 void |
s.setstate(flags) |
根据给定的 flags 标志位,将流 s 中对应条件状态位置位,flags 的类型为
strm::iostate,返回 void |
s.rdstate() |
返回流 s 的当前条件状态,返回值类型为 strm::iostate |
iostate
提供了表达流状态的完整功能,这个类型应作为一个位集合来使用,IO 库定义了
4 个 iostate 类型的 constexpr 值表示特定的位模式
1 2 3 4
| auto old_state = cin.rdstate(); cin.clear(); process_input(cin); cin.setsate(old_state);
|
clear
不接受参数的版本清除所有错误标志位,带参数的版本将所需位复位来生成新的状态,下面的代码将
failbit 和 badbit 复位,但保持 eofbit 不变
1
| cin.clear(cin.rdstae() & ~cin.failbit & ~cin.badbit);
|
管理输出缓冲
- 程序正常结束,作为 main 函数的 return
操作的一部分,缓冲刷新被执行
- 缓冲区满时,需要刷新缓冲,而后新的数据才能继续写入缓冲区
- 使用操纵符 endl 来显式刷新缓冲区
- 在每个输出操作之后,可以用操纵符 unitbuf
设置流的内部状态,来清空缓冲区。默认情况下,对 cerr 是设置 unitbuf
的,因此写到 cerr 的内容都是立即刷新的
- 一个输出流可能被关联到另一个流,在这种情况下,当读写被关联的流时,关联到的流的缓冲区会被刷新。例如,默认情况下,cin
和 cerr 都关联到 cout,因此,读 cin 或写 cerr 都会导致 cout
的缓冲区被刷新
刷新输出缓冲区
1 2 3
| cout << "hi!" << endl; cout << "hi!" << flush; cout << "hi!" << ends;
|
unibuf 操纵符
1 2
| cout << unitbuf; cout << nounitbuf;
|
关联输入和输出流
当一个输入流被关联到一个输出流时,任何试图从输入流读取数据的操作都会先刷新关联的输出流,标准库将
cout 和 cin 关联在一起
tie
有两个重载版本,带参数的和不带参数的。带参数的版本如果当前关联一个输出流,则返回指向这个流的指针,否则返回空指针。带参数的版本则用来关联
ostream
1 2 3 4
| cin.tie(&cout); ostream *old_tie = cin.tie(nullptr); cin.tie(&cerr); cin.tie(old_tie);
|
每个流同时最多关联到一个流,但多个流可以同时关联到同一个 ostream
string 流
1 2 3 4
| sstream strm; sstream strm(s); strm.str(); strm.str(s);
|
istringstream
如果想处理 string 序列中的单词或数字,使用 istringstream 会很方便
假如有个文件,每一行是人名和他的电话号码,每个人只有一个人名但可能有多个号码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
| struct PersonInfo { string name; vector<string> phones; };
string line, word; vector<PersonInfo> people;
while (getline(cin, line)) { PersonInfo info; istringstream record(line); record >> info.name; while (record >> word) info.phones.push_back(word); people.push_back(info); }
|
istringstream 与每行的输入 line
绑定,然后依次读取其中的数据,数据读取完后,触发”文件读取“信号。