文件操作补充 — 缓冲与错误处理基础
补充 stdio.h 中
fflush、setbuf、setvbuf的详细说明,以及perror的基础用法。
fflush — 强制刷新缓冲区
int fflush(FILE *stream);强制将输出缓冲区的内容写入文件/设备。
| 参数 | 行为 |
|---|---|
stream != NULL | 刷新指定流 |
stream == NULL | 刷新所有打开的输出流 |
关键概念:
fflush(stdin)是未定义行为(C 标准规定fflush仅对输出流有效)。某些编译器(如 MSVC)允许,但不可移植。
典型场景:
- 在
fork()前刷新,避免子进程继承未刷新的缓冲区导致重复输出 - 交互式程序在
printf后立即fflush(stdout)确保提示符显示
setbuf — 设置缓冲区
void setbuf(FILE *stream, char *buf);| 调用 | 效果 |
|---|---|
setbuf(fp, NULL) | 设置为无缓冲(_IONBF) |
setbuf(fp, buf) | 设置为全缓冲(_IOFBF),缓冲区大小为 BUFSIZ(通常 8192) |
buf必须大小为BUFSIZ字节,且在流关闭前保持有效(不可为局部自动变量)。
setvbuf — 精细缓冲控制
int setvbuf(FILE *stream, char *buf, int mode, size_t size);| mode | 含义 |
|---|---|
_IOFBF | 全缓冲:缓冲区满时才写入 |
_IOLBF | 行缓冲:遇到换行符时写入(终端默认) |
_IONBF | 无缓冲:逐字节写入(stderr 默认) |
在打开文件后、执行任何 I/O 前调用
setvbuf才有效。setbuf(fp, NULL)等价于setvbuf(fp, NULL, _IONBF, 0)。
默认缓冲策略
| 流类型 | 缓冲模式 |
|---|---|
stderr | 无缓冲 |
stdin / stdout(连接终端) | 行缓冲 |
stdin / stdout(重定向到文件) | 全缓冲 |
fopen 打开的普通文件 | 全缓冲 |
perror — 输出错误信息
void perror(const char *s);向 stderr 输出格式:s: 错误描述\n,其中错误描述来自当前 errno 值。
FILE *fp = fopen("nonexistent.txt", "r");
if (!fp) {
perror("fopen failed");
/* 输出: fopen failed: No such file or directory */
}