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() |
清除所有错误状态,恢复流为良好状态 |
评论区
欢迎在评论区指出文档错误,为文档提供宝贵意见,或写下你的疑问