C++的IO流深入理解(上)

1.C 语言的输入与输出

1. 核心 IO 函数
场景 函数 作用
标准输入 / 输出 printf / scanf 格式化打印、读取数据
文件 IO fopen / fclose / fprintf / fscanf / fread / fwrite 文件的打开关闭、读写操作
2.典型痛点

1.类型不安全:printf/scanf依赖格式符(如%d/%s),格式符与变量类型不匹配会导致未定义行为,甚至内存错误。

2.缓冲区问题:输入输出缓冲区的残留(如scanf留下的换行符)会干扰后续操作,需要手动处理。

3.错误处理繁琐:scanf失败后不会自动终止,后续输入会被持续阻塞,需手动判断返回值。

4.面向对象支持差:无法直接输出自定义类型(如结构体、类对象),需要手动写格式化逻辑。

5.资源管理麻烦:文件句柄、缓冲区需手动管理,容易出现内存泄漏或文件未关闭的问题。

2.流是什么?

"流" 是 IO 操作的抽象模型,也是理解 C++IO 流的基础。

1. 定义

流是数据从源端到目的端的有序、连续传输通道,可以类比现实中的 "水流":

源端:数据的生产者(如键盘、文件、内存字符串)

目的端:数据的消费者(如屏幕、文件、内存字符串)

流的方向:输入流(数据流入程序)、输出流(数据流出程序)

2. 核心特性

单向性:基础流分为输入 / 输出两种方向(双向流是两者的组合)。

缓冲性:为减少直接 IO 的开销,流会先将数据存入内存缓冲区,缓冲区满 / 程序结束 / 主动刷新时,再将数据写入设备。

抽象性:程序无需关心底层设备差异(键盘 / 文件 / 网络),只需通过统一的流接口操作数据。

3. 流的分类(按交互对象)

标准 IO 流:与控制台(键盘 / 屏幕)交互

文件 IO 流:与磁盘文件交互

字符串流:与内存中的字符串交互(stringstream)

3.C++IO 流

C++ 的 IO 流是一套面向对象的类层次结构,所有流类都继承自ios_base,核心分支如下:
ios_base → ios → istream/ostream → iostream/ifstream/ofstream/stringstream

1 .C++ 标准 IO 流(控制台交互)

标准 IO 流是 C++ 预定义的全局流对象,属于istream/ostream的实例。

2.核心对象
对象 类型 作用 缓冲特性
cin istream 标准输入流(键盘读取) 有缓冲
cout ostream 标准输出流(屏幕打印) 有缓冲
cerr ostream 标准错误流(错误信息打印) 无缓冲(直接输出)
clog ostream 标准日志流(日志信息打印) 有缓冲
3.关键特性与用法

运算符重载:<<(插入运算符,输出)和>>(提取运算符,输入)是 C++IO 流的核心,支持链式调用,且自动处理类型,无需格式符:

cpp 复制代码
int a = 10;
double b = 3.14;
string s = "hello";
cout << "a=" << a << ", b=" << b << ", s=" << s << endl; // 自动适配类型

流状态位:流操作会维护 4 种状态位,用于判断操作是否成功:

1.goodbit:操作正常

2.eofbit:读取到文件 / 输入末尾

3.failbit:操作失败(如类型不匹配)

4.badbit:流发生严重错误(如设备故障)

5.可通过cin.fail()/cin.clear()/cin.ignore()检查、重置状态或清空缓冲区。

格式化控制:通过<iomanip>头文件的函数控制输出格式:

cpp 复制代码
cout << fixed << setprecision(2) << 3.14159; // 保留2位小数,输出3.14
cout << setw(5) << 10; // 设置输出宽度为5,默认右对齐
4.endl与\n的区别:

1.endl:输出换行符 + 强制刷新缓冲区

2.\n:仅输出换行符,不刷新缓冲区(效率更高,推荐优先使用)

5. 常见坑与解决方案

cin >> s遇到空格会停止读取字符串,需用getline(cin, s)读取整行。

混合使用cin和getline时,cin残留的换行符会被getline读取,需用cin.ignore()清空缓冲区。

谢谢

相关推荐
SilentSamsara1 小时前
DuckDB + Python:嵌入式 OLAP 数据库的轻量分析实战
开发语言·数据库·python·微服务
炘爚1 小时前
Phase 4:业务线程池 — IO/计算解耦
linux·c++
张小姐的猫1 小时前
【Linux】多线程 —— 线程池 | 单例模式 | 常见锁
linux·运维·服务器·c++·单例模式·设计模式·策略模式
无限进步_1 小时前
【Linux】进程状态、僵尸与孤儿、进程调度
linux·运维·服务器·开发语言·数据结构·算法
郝学胜-神的一滴1 小时前
力扣 662 :二叉树最大宽度
java·数据结构·c++·python·算法·leetcode·职场和发展
仙俊红1 小时前
反射到底解决什么问题?
java·开发语言
大阳1231 小时前
ARM.9(RGBLCD,PWM)
c语言·开发语言·汇编·单片机·嵌入式硬件·pwm·rgblcd
加油码2 小时前
Linux IO 多路转接详解:从 select、poll 到 epoll
linux·c++
珊瑚里的鱼2 小时前
C++14 和 C++17 的核心新特性
开发语言·c++