C++_IO库
IO 库
C++ 的 IO(输入输出)基于流(stream)。
可以把流理解成:
数据流动的通道
- 输入流:数据流入程序
- 输出流:数据从程序流出
常见对象:
cin:标准输入cout:标准输出cerr:标准错误输出
常见操作:
>>:读入数据<<:输出数据getline:读取一整行
IO 库的常见组件
istream:输入流类型ostream:输出流类型iostream:既能输入也能输出的流类型cin:istream对象,从标准输入读cout:ostream对象,向标准输出写cerr:ostream对象,通常输出错误信息>>:从输入流提取数据<<:向输出流插入数据getline:从输入流读取一行到string
IO 库类型和头文件
| 头文件 | 主要类型 |
|---|---|
iostream |
istream、ostream、iostream |
fstream |
ifstream、ofstream、fstream |
sstream |
istringstream、ostringstream、stringstream |
说明:
iostream:控制台 IOfstream:文件 IOsstream:字符串 IO
宽字符版本
很多 IO 类型还有宽字符版本,名字前加 w:
wcinwcoutwcerrwifstreamwostringstream
基础阶段一般先掌握普通字符版本即可。
IO 对象不能拷贝
IO 对象不能拷贝、不能赋值。
因此:
- 不能按值传递流对象
- 不能返回流对象(按值)
- 通常要用引用传递和返回
例如:
1 | istream& read(istream &is) { |
注意:
- 因为读写流会改变流状态,所以通常不能是
const引用
标准输入输出
cin、cout、cerr
1 | int x; |
说明:
cin:读数据cout:正常输出cerr:错误信息,通常不经过普通缓冲或更适合及时显示错误
>> 运算符
>> 从输入流中读取数据,并跳过开头的空白字符(空格、换行、Tab 等)。
1 | int n; |
特点:
- 以空白作为分隔
- 读
string时,遇到空格就停止
例如输入:
1 | hello world |
1 | string s; |
结果 s == "hello"
getline
getline 用于读取一整行,包括空格,直到换行符为止。
1 | string line; |
例如输入:
1 | hello world |
则 line == "hello world"
>> 与 getline 混用问题
这是常见易错点。
1 | int n; |
getline 可能读到的是上一次输入留下的换行符,导致 line 为空串。
解决方法:
1 | cin >> n; |
或先处理掉换行符再读整行。
IO 条件状态
流对象会维护自己的状态,用来表示当前 IO 是否成功。
常见状态位:
| 状态 | 含义 |
|---|---|
badbit |
流严重错误,流已损坏 |
failbit |
本次 IO 操作失败 |
eofbit |
到达文件结束 |
goodbit |
流状态正常,值为 0 |
常用状态检查函数
| 函数 | 含义 |
|---|---|
s.eof() |
到达文件末尾返回 true |
s.fail() |
发生失败或严重错误返回 true |
s.bad() |
严重错误返回 true |
s.good() |
流状态完全正常返回 true |
s.rdstate() |
返回当前状态 |
s.clear() |
清除所有错误状态 |
s.clear(flags) |
将状态设为指定值 |
s.setstate(flags) |
添加某些状态位 |
流作为条件
最常见写法:
1 | int x; |
原因:
cin >> x成功时,流处于可用状态,条件为真- 输入失败时,条件为假,循环结束
这也是最推荐的输入循环方式。
输入失败后的恢复
例如输入类型不匹配:
1 | int x; |
如果用户输入 "abc",则读取失败,流进入失败状态。
这时后续输入通常也会继续失败,除非恢复状态:
1 | cin.clear(); // 清除错误状态 |
管理输出缓冲
输出流通常带有缓冲区。
程序写入的数据可能先放进缓冲区,不会立刻显示或写到设备。
刷新缓冲区
常见刷新方式:
1 | cout << endl; // 输出换行并刷新缓冲区 |
说明:
endl= 换行 + 刷新- 如果只想换行,不一定要用
endl - 频繁刷新会影响性能
例如:
1 | cout << "hello\n"; // 只换行,不保证立刻刷新 |
unitbuf
可以让流在每次输出后都自动刷新:
1 | cout << unitbuf; |
取消:
1 | cout << nounitbuf; |
注意
如果程序异常崩溃,缓冲区中的内容可能来不及刷新,因此有些输出可能看不到。
文件输入输出
fstream 头文件支持文件 IO:
ifstream:读文件ofstream:写文件fstream:读写文件
文件流的基本操作
创建并打开文件
1 | ifstream in("input.txt"); |
也可以先创建,再打开:
1 | ifstream in; |
关闭文件
1 | in.close(); |
关闭后,该流不再和文件绑定。
判断是否成功打开
1 | ifstream in("input.txt"); |
也可以:
1 | if (in.is_open()) { |
fstream 特有操作
| 操作 | 含义 |
|---|---|
fstream f; |
创建未绑定文件的流 |
fstream f(s); |
打开名为 s 的文件 |
fstream f(s, mode); |
按指定模式打开文件 |
f.open(s); |
打开文件 |
f.close(); |
关闭文件 |
f.is_open(); |
判断文件是否已打开 |
说明:
s可以是string或 C 风格字符串- 文件流构造函数通常是
explicit
文件打开模式
常见文件模式:
| 模式 | 含义 |
|---|---|
in |
读方式打开 |
out |
写方式打开 |
app |
每次写前定位到文件末尾 |
ate |
打开后立即定位到文件末尾 |
trunc |
截断文件原内容 |
binary |
二进制方式打开 |
常见组合
1 | ofstream out("a.txt"); // 默认写 |
app 和 ate 的区别
app:每次写之前都跳到文件末尾ate:打开文件后先到末尾,但之后仍可移动位置
复习时先记:
想“追加写入”,常用
app
out 的默认行为
对于 ofstream,若只用 out 打开文件,通常会清空原文件内容(相当于带 trunc)。
如果不想清空、想追加,应该使用:
1 | ios::app |
文件读写示例
逐个单词读取
1 | ifstream in("input.txt"); |
按行读取
1 | ifstream in("input.txt"); |
写入文件
1 | ofstream out("output.txt"); |
string 流
sstream 头文件定义了在字符串上进行 IO 的类型:
istringstream:从string读ostringstream:向string写stringstream:可读可写
它本质上是把字符串当作流来处理。
stringstream 特有操作
| 操作 | 含义 |
|---|---|
stringstream ss; |
创建空流 |
stringstream ss(s); |
用字符串 s 初始化流 |
ss.str() |
返回流中的字符串副本 |
ss.str(s) |
用字符串 s 替换流内容 |
istringstream 的常见用途
拆分一行中的数据
1 | string line = "10 20 30"; |
适合:
- 先按行读入
- 再对该行内容进一步解析
与 getline 配合
这是非常常见的模式:
1 | string line; |
作用:
- 外层按行读
- 内层按单词拆分
ostringstream 的常见用途
把各种类型的数据拼成一个字符串:
1 | ostringstream oss; |
适合:
- 格式化字符串
- 拼接输出内容
- 构造日志信息
三类 IO 的区别
| 类型 | 用途 |
|---|---|
iostream |
控制台输入输出 |
fstream |
文件输入输出 |
sstream |
字符串输入输出 |
常见输入模式总结
读到 EOF
1 | int x; |
按行读取
1 | string line; |
先按行读,再按词拆
1 | string line; |
易错点总结
>> 读取字符串时遇到空白就停止
1 | cin >> s; |
不会读入整行。
读取整行要用 getline
1 | getline(cin, line); |
>> 和 getline 混用时要处理残留换行符
常用:
1 | cin.ignore(); |
流对象不能拷贝
函数参数和返回值一般用引用。
文件流打开后要先检查是否成功
1 | if (!in) { ... } |
ofstream 默认可能清空原文件
若要追加,使用:
1 | ios::app |
endl 会刷新缓冲区
如果只想换行,用 '\n' 更轻量。
输入失败后要 clear() 才能继续使用流
必要时还要配合 ignore() 丢弃错误输入。
小结
C++ 标准库把 IO 统一成“流”的形式:
iostream:处理标准输入输出fstream:处理文件sstream:处理字符串
最常见的复习重点:
cin / cout / cerr>> / << / getline- 流状态检查
- 文件流打开与模式
istringstream解析字符串




