输入输出库
C 标准库的输入输出能力主要由头文件 <stdio.h> 提供。它基于“流” (Stream) 这一抽象:程序通过流读写字节序列,而不直接讨论操作系统、文件描述符、设备驱动等实现细节。
注意
本章严格讨论 C 标准库的语义,不引入 POSIX / Windows 的系统调用层知识。
1. 学习目标
- 理解什么是 I/O 流,以及
FILE/FILE*的角色。 - 能正确地打开文件、读写数据、检查错误、关闭文件。
- 能区分无格式 I/O 与有格式 I/O,并知道它们各自的风险点与使用边界。
- 能进行基本的文件定位(并理解文本流定位的限制)。
2. 本章目录
3. 一个总原则
I/O 代码应始终把“返回值检查”当作主流程的一部分,而不是补丁步骤。无论是读取失败、到达文件结束,还是写入失败,只有显式检查状态,才能保证后续逻辑建立在有效前提上。
4. EOF 与错误要区分
读取接口返回失败时,不一定是“真正错误”,也可能只是到达输入末尾。标准库提供了 feof 和 ferror 用于区分这两种状态。把二者混为一谈,会让错误处理路径和正常结束路径纠缠在一起。
5. 文本流与二进制流的边界
标准把文件流分为文本模式与二进制模式。文本流允许实现对换行等表示做适配,因此定位语义会受到额外限制;二进制流更接近原始字节序列。只要代码依赖“精确字节位置”,就应优先采用二进制语义并明确读写单位,避免把文本模式下的实现差异带入协议层逻辑。
6. 缓冲行为与刷新时机
流通常带缓冲,写入调用返回并不总意味着数据已经落到外部介质。需要及时可见的输出,应在关键边界显式 fflush,并在关闭流时检查返回状态。把“写入成功”与“写入已提交”区分开,I/O 错误处理会更完整。
7. 习题
#11401
⚡3⏳2
写一个程序,把一行文本从标准输入读入,并原样输出到标准输出。
要求:
- 不使用
scanf("%s", ...); - 检查读入是否成功。
#11402
⚡4⏳3
写一个程序:从标准输入读入两个 int,输出它们的和。
要求:检查输入函数的返回值;当输入失败时给出提示并退出。