文件操作补充 — 缓冲与错误处理基础

补充 stdio.h 中 fflushsetbufsetvbuf 的详细说明,以及 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 */
}

跨语言参考