14 Stream¶
说明
本文档仅涉及部分内容,仅可用于复习重点知识
流(stream):数据的有序序列,C++ 用流来进行输入输出操作
头文件:
<iostream>
:标准输入输出流(cin
,cout
,cerr
,clog
)<fstream>
:文件输入输出流(ifstream
,ofstream
,fstream
)<sstream>
:字符串流(istringstream
,ostringstream
,stringstream
)
优点:
- 类型安全更好:流操作符(
<<
,>>
)会根据变量类型自动选择合适的格式,避免了类型不匹配带来的错误,减少了运行时错误的可能性 - 可扩展性强:可以为自定义类型重载流操作符,实现自定义类型的输入输出,方便扩展和维护
- 更面向对象:流是类的实例,支持继承、多态等面向对象特性,便于与 C++ 其他特性结合使用
缺点:
- 语法更繁琐:相比 C 语言的
printf
/scanf
,C++ 流的语法更长、更复杂,代码量可能增加 - 效率较低:流的实现更复杂,通常运行速度比 C 的标准 I/O 函数慢,尤其是在大量数据处理时
1 流命名约定¶
1.1 标准输入输出流¶
cin
:标准输入cout
:标准输出cerr
:标准错误(不缓冲 unbuffered)clog
:标准日志(缓冲 buffered)
缓冲
在 C++ 中,缓冲(buffered)和不缓冲(unbuffered)指的是输出数据时,数据是否会先暂存在内存的缓冲区中,还是直接输出到目标设备(如屏幕、文件等)
- 缓冲:输出的数据会先存放在内存的缓冲区里,等到缓冲区满了或者遇到换行、手动刷新(如
flush
)时,才会一次性输出到目标设备。这样可以减少输出操作的次数,提高效率 - 不缓冲:输出的数据不会存放在缓冲区,而是每次输出操作都会立即发送到目标设备。这样可以保证信息及时显示,但效率较低
流缓冲区:
- 每个 IO 流对象(如
cin
、cout
、ifstream
等)都有一个流缓冲区(stream buffer) - 类
streambuf
定义了缓冲区的抽象和基本操作 - 流对象的成员函数
rdbuf()
可以返回指向其缓冲区的指针 - 对于
streambuf
对象,<<
操作符被重载,可以直接连接两个流的缓冲区,实现高效的数据传输
1.2 文件流¶
ofstream
:输出文件流(写文件)ifstream
:输入文件流(读文件)fstream
:读写文件流
常用打开模式(可组合):
ios::in
:读ios::out
:写ios::app
:追加ios::trunc
:截断ios::binary
:二进制ios::ate
:打开文件后定位到文件末尾
open(const char *, int flags, int)
:用于打开指定的文件,可以指定打开模式(如只读、只写、二进制等)
将一个文件的内容复制到标准输出(即屏幕):
1.3 字符串流¶
istringstream
:从字符串读取ostringstream
:向字符串写入stringstream
:读写字符串
2 流运算符¶
- Extractor:
>>
- Inserters:
<<
- Manipulators:操纵符
- 其他
2.1 其他输入操作¶
1.int get()
- 作用:返回流中的下一个字符(作为
int
类型返回) - 返回值:如果没有字符可读(到达流末尾),返回
EOF
(end of file,文件结束标志)
2.istream& get(char& ch)
- 作用:将下一个字符读入到参数
ch
中 - 说明:和
int get()
类似,但直接把字符存入变量,而不是返回 - 返回值:返回流对象本身(可用于链式调用)
3.istream& getline(istream& is, string& str, char delim='\n')
- 作用:从输入流中读取一行(或以指定分隔符结尾的字符串)到
str
中,默认以换行符\n
为分隔符 - 特点:是一个自由函数(非成员函数)
4.ignore(int limit = 1, int delim = EOF)
- 作用:跳过输入流中的若干字符,直到跳过
limit
个字符或遇到分隔符delim
为止 - 特点:是
istream
的成员函数。遇到分隔符时也会跳过它
5.int gcount()
作用:返回上一次输入操作实际读取的字符数
6.void putback(char)
作用:将一个字符“放回”输入流,使其成为下一个要读取的字符
7.char peek()
作用:查看输入流中的下一个字符,但不提取(不移除)它
2.2 其他输出操作¶
1.put(char)
作用:向输出流中写入一个字符
2.flush()
作用:强制将缓冲区中的内容立即输出到目标设备(如屏幕),而不是等缓冲区满或遇到换行时才输出
2.3 格式设置操纵符¶
头文件:<iomanip>
操纵符 | 作用 | 类型 |
---|---|---|
std::endl |
输出换行并刷新缓冲区 | O |
std::setw(n) |
设置字段宽度为 n,下一个输出项有效 | O |
std::setfill(c) |
设置填充字符为 c(与 setw 配合使用) |
O |
std::setprecision(n) |
设置浮点数有效数字位数 | O |
std::fixed |
以定点格式输出浮点数 | O |
std::scientific |
以科学计数法格式输出浮点数 | O |
std::left |
左对齐 | O |
std::right |
右对齐 | O |
std::hex |
以十六进制格式输出整数 | I/O |
std::dec |
以十进制格式输出整数(默认) | I/O |
std::oct |
以八进制格式输出整数 | I/O |
std::showbase |
显示进制前缀(如 0x, 0) | O |
std::showpoint |
强制显示浮点数的小数点 | O |
std::uppercase |
用大写字母输出十六进制和科学计数法 | O |
std::nouppercase |
用小写字母输出十六进制和科学计数法 | O |
std::boolalpha |
以 true /false 输入/输出 bool 类型 |
I/O |
std::noboolalpha |
以 1/0 输入/输出 bool 类型 |
I/O |
std::ws |
跳过输入流中的所有空白字符 | I |
2.3.1 自定义操纵符¶
2.4 格式控制标志¶
标志(flag) | 作用 |
---|---|
ios::skipws |
跳过前导空白字符(如空格、换行等) |
ios::left, ios::right |
输出对齐方式(左对齐、右对齐) |
ios::internal |
在符号和数值之间填充(如负号和数字之间) |
ios::dec, ios::hex, ios::oct |
数字的进制格式(十进制、十六进制、八进制) |
ios::showbase |
显示数字的进制前缀(如0x、0) |
ios::showpoint |
总是显示小数点(即使是整数) |
ios::uppercase |
用大写字母表示进制前缀和科学计数法中的E |
ios::showpos |
正数前显示加号(+) |
2.4.1 使用操纵符¶
setiosflags(flags)
:设置指定的格式标志resetiosflags(flags)
:清除指定的格式标志
2.4.2 使用流的成员函数¶
setf(flags)
:设置格式标志unsetf(flags)
:清除格式标志
获取当前标志:
3 流状态¶

状态标志 | 说明 |
---|---|
goodbit |
没有错误,流处于良好状态 |
eofbit |
已到达输入流末尾(EOF) |
failbit |
输入/输出操作失败(格式错误等) |
badbit |
流发生严重错误(如物理读写错误) |
检查流状态的成员函数:
函数名 | 作用说明 |
---|---|
good() |
流处于良好状态(无错误) |
eof() |
是否到达文件/流末尾 |
fail() |
是否发生格式错误或其他错误 |
bad() |
是否发生严重错误 |
clear() |
清除所有错误状态,恢复流为良好状态 |
评论区
欢迎在评论区指出文档错误,为文档提供宝贵意见,或写下你的疑问