一、前置基础:带参数的 main 函数

带参 main 函数是文件操作程序的核心基础,用于程序运行时动态传入文件名、操作参数,无需硬编码,格式如下:

int main(int argc, char *argv[])
  • argc:命令行参数的总个数,程序名本身为第 1 个参数
  • argv:字符串数组,存储每个命令行参数;argv[0]为程序名,argv[1]~argv[argc-1]为用户传入的自定义参数

二、文件 IO(系统调用级 IO)

1. 核心概述

文件 IO 是 Linux 原生的系统调用级 IO 函数,又称低级 IO,遵循 Linux一切皆文件的核心思想,可操作所有类型文件(普通文件、设备文件、管道、socket 等)。

2. 核心特性

  1. 无缓冲区:每次调用 IO 函数都会触发用户态与内核态的切换,频繁调用会降低读写效率
  2. 文件标识:文件描述符int fd,非负整数,可用范围 0~1023
  3. 预打开的特殊描述符:程序运行自动打开,无需手动创建
    • 0:标准输入(stdin),对应键盘
    • 1:标准输出(stdout),对应终端
    • 2:标准错误(stderr),对应终端
  4. 平台限制:仅适用于 UNIX/Linux 平台,不可跨标准 C 平台移植
  5. 描述符分配规则:优先使用当前可用的最小非负整数

3. 标准操作流程

打开文件(open)→ 操作文件(read/write/lseek)→ 关闭文件(close)

4. 核心 API 速查

表格

函数 核心原型 核心功能 参数要点 返回值规则
open int open(const char *pathname, int flags, mode_t mode); 打开 / 创建文件,返回文件描述符

1. pathname:文件路径 + 文件名

2. flags必选:O_RDONLY (只读)/O_WRONLY (只写)/O_RDWR (读写),三选一

3. flags可选:O_CREAT (不存在则创建)/O_APPEND (追加写)/O_TRUNC (清空写)

4. mode:仅 O_CREAT 时必填,新建文件权限,最终权限 =mode & ~umask,常用 0666

成功:非负文件描述符失败:-1
close int close(int fd); 关闭文件,释放文件描述符资源 fd:待关闭的文件描述符 成功:0失败:-1
read ssize_t read(int fd, void *buf, size_t count); 从文件读取数据到缓冲区

1. fd:文件描述符

2. buf:存储读取内容的缓冲区

3. count:期望读取的字节数

成功:实际读取到的字节数失败:-1文件末尾:0
write ssize_t write(int fd, const void *buf, size_t count); 将缓冲区数据写入文件

1. fd:文件描述符

2. buf:待写入内容的首地址

3. count:待写入的字节数

成功:实际写入的字节数失败:-1
lseek off_t lseek(int fd, off_t offset, int whence); 移动文件读写光标,改变读写位置

1. fd:文件描述符

2. offset:相对偏移量,正数后移,负数前移3. whence:基准位置:SEEK_SET (文件开头)/SEEK_CUR (当前位置)/SEEK_END (文件末尾)

成功:光标距文件开头的字节数失败:-1

5. 高频考点与必记规则

  1. 先写后读读不到内容的核心原因:写入完成后,光标停在文件末尾,需通过lseek移动光标到目标位置才能读取。
  2. 经典用法:
    • 先写后读:lseek(fd, 0, SEEK_SET) 回到文件开头再读取
    • 获取文件大小:lseek(fd, 0, SEEK_END),返回值即为文件总字节数
  3. 资源管理:文件描述符数量有限,使用完毕必须调用 close 关闭,否则会造成资源泄漏。

三、标准 IO(C 标准库 IO)

1. 核心概述

标准 IO 是 C 语言标准库在系统调用之上封装的 IO 函数,又称高级 IO,核心优化是增加了缓冲区机制,主要用于操作普通文件,可跨所有标准 C 平台移植。

2. 核心特性

  1. 带缓冲区:减少用户态与内核态的切换次数,批量读写数据,读写效率远高于无缓冲的文件 IO
  2. 文件标识:文件流指针FILE *fp,非空指针标识打开的文件
  3. 预打开的特殊流指针:程序运行自动打开,stdin(标准输入)、stdout(标准输出)、stderr(标准错误)
  4. 跨平台性:兼容所有标准 C 平台,可移植性极强
  5. 适用范围:主要用于普通文件操作,无法直接操作设备文件、管道等特殊文件

3. 核心重点:缓冲区机制(与文件 IO 的核心区别)

标准 IO 根据使用场景分为两类缓冲区,刷新规则是高频必记考点:

缓冲区类型 适用场景 自动刷新条件
行缓冲 标准输入 (stdin)、标准输出 (stdout)

1. 程序正常执行结束

2. 流指针被 fclose 关闭

3. 缓冲区被填满(默认 1K)

4. 写入内容包含换行符\n

5. 主动调用 fflush () 刷新

全缓冲 磁盘普通文件

1. 程序正常执行结束

2. 流指针被 fclose 关闭

3. 缓冲区被填满(默认 4K)

4. 主动调用 fflush () 刷新⚠️ 遇\n不会自动刷新

4. 标准操作流程

打开文件(fopen)→ 操作文件(各类读写函数)→ 关闭文件(fclose)

5. 核心 API 速查

5.1 打开 / 关闭文件
函数 核心原型 核心功能 参数要点 返回值规则
fopen FILE *fopen(const char *pathname, const char *mode); 打开 / 创建文件,返回流指针

1. pathname:文件路径 + 文件名

2. mode:打开模式,核心速记:r/r+:只读 / 读写,文件必须存在w/w+:只写 / 读写,不存在则创建,存在则清空a/a+:追加 / 读写,不存在则创建,存在则追加写

成功:非空 FILE * 流指针失败:NULL
fclose int fclose(FILE *stream); 关闭文件流,刷新缓冲区,释放资源 stream:待关闭的文件流指针 成功:0
5.2 四大类读写函数
读写类型 核心函数 核心原型 功能与关键特性 返回值规则
块读写 fread size_t fread(void *ptr, size_t size, size_t nmemb, FILE *stream); 以数据块为单位读取文件,遇空格 / 换行不结束,适合二进制文件、大数据块读写 成功:实际读取的完整块数量失败 / 文件末尾:0
fwrite size_t fwrite(const void *ptr, size_t size, size_t nmemb, FILE *stream); 以数据块为单位写入文件 成功:实际写入的完整块数量失败:0
格式读写 fscanf int fscanf(FILE *stream, const char *format, ...); 按指定格式读取文件,用法与 scanf 完全一致,scanf等价于fscanf(stdin, ...) 成功:成功读取的变量个数失败 / 文件末尾:小于格式控制符数量
fprintf int fprintf(FILE *stream, const char *format, ...); 按指定格式写入文件,用法与 printf 完全一致,printf等价于fprintf(stdout, ...) 成功:写入的字节数失败:负数
字符读写 fgetc int fgetc(FILE *stream); 读取文件的单个字符 成功:读取到的字符失败 / 文件末尾:EOF (-1)
fputc int fputc(int c, FILE *stream); 向文件写入单个字符 成功:写入的字符失败:EOF
行读写 fgets char *fgets(char *s, int size, FILE *stream); 按行读取文件,遇换行结束,换行符会被读取,最多读 size-1 个字节,末尾自动补 '\0' 成功:存储内容的缓冲区首地址失败 / 文件末尾:NULL
fputs int fputs(const char *s, FILE *stream); 向文件写入一行字符串,不自动添加换行符 成功:写入的字节数失败:EOF
5.3 辅助操作函数
函数 核心原型 核心功能 高频用法
fseek int fseek(FILE *stream, long offset, int whence); 移动文件读写光标,参数规则同 lseek 先写后读:fseek(fp, 0, SEEK_SET) 回到文件开头
fflush int fflush(FILE *stream); 主动刷新缓冲区,将缓冲区数据写入底层 printf 无 \n 时,fflush(stdout)强制打印到终端
feof int feof(FILE *stream); 判断文件是否到达末尾 循环读取文件时,判断读取结束条件,到达末尾返回非 0

6. 必记规则

  1. 先写后读读不到内容:写入完成后光标停在文件末尾,需通过fseek移动光标到目标位置再读取。
  2. 写入文件后看不到内容:全缓冲模式下,缓冲区未填满 / 未关闭 / 未主动刷新,数据仍在缓冲区,未写入磁盘,可通过fflush强制刷新。
  3. fscanf遇空格自动跳过,适合读取格式化文本;fgets会读取换行符,使用时需注意处理末尾的\n

四、文件 IO 与标准 IO 核心对比表

对比维度 文件 IO 标准 IO
本质 Linux 系统调用,内核级操作 C 标准库封装,在系统调用之上的用户态封装
缓冲区 无缓冲区,每次调用都触发内核态切换 有行缓冲 / 全缓冲,减少内核态切换,效率更高
文件标识 文件描述符 int fd 文件流指针 FILE *fp
适用范围 所有 Linux 文件类型(普通文件、设备、管道、socket 等) 主要用于普通文件,无法直接操作特殊设备文件
跨平台性 仅适用于 UNIX/Linux 平台 兼容所有标准 C 平台,可移植性强
操作粒度 字节级读写,灵活度高 支持块、格式、字符、行多种读写模式,开发更便捷
效率 频繁调用效率低,单次大数据读写效率尚可 批量读写效率远高于文件 IO,频繁小数据读写优势显著

Logo

汇聚全球AI编程工具,助力开发者即刻编程。

更多推荐