核心结论 fopen 是 C 语言标准库 stdio 头文件里面的文件打开函数,作用是按照指定模式打开外部文件,成功之后返回一个 FILE 类型的文件指针,后续所有文件读写定位关闭操作,都依靠这个 FILE 指针完成,如果打开失败函数会返回空指针 NULL,写代码的时候必须做返回值判断,这是 fopen 函数最核心的使用要点。fopen 支持多种打开模式,分为只读只写追加二进制文本等类别,不同模式决定文件是否新建是否覆盖原有内容,是否允许读写同时进行,很多初学者踩坑就是选错打开模式,导致原有数据被清空,或者无法读取文件,fopen 本身不会自动创建目录,如果文件所在文件夹不存在,哪怕模式是 w 也会打开失败。
函数原型与参数说明
函数原型 FILE fopen (const char filename, const char mode)
| 参数 | 含义 | 说明 |
|---|---|---|
| filename | 文件路径 | 可以写相对路径或者绝对路径,路径里面反斜杠在 C 字符串要写成两个反斜杠 |
| mode | 打开模式 | 控制读写权限新建覆盖追加等行为 |
| 返回值 | FILE 指针 | 成功返回文件指针,失败返回 NULL |
常用打开模式对照表
| 模式字符串 | 功能说明 | 文件不存在时 | 文件已存在时 |
|---|---|---|---|
| r | 只读,从文件开头读取 | 打开失败 | 保留原有内容,指针定位到开头 |
| w | 只写 | 创建新文件 | 清空原有全部内容 |
| a | 追加写入 | 创建新文件 | 保留原有内容,写入位置在文件末尾 |
| r+ | 读写模式 | 打开失败 | 保留原有内容,指针定位到开头 |
| w+ | 读写模式 | 创建新文件 | 清空原有全部内容 |
| a+ | 读写追加 | 创建新文件 | 保留原有内容,读从开头,写永远追加末尾 |
| rb wb ab | 二进制版本,对应上面 r w a | 用于图片二进制文件,避免换行符转换 | |
| r+b w+b a+b | 二进制读写版本,对应 r+ w+ a+ | 二进制文件读写推荐使用 |
完整使用步骤
第一步 引入头文件,代码开头加上 include stdio.h,因为 fopen 和 FILE 类型都定义在这个头文件内。
第二步 定义 FILE 指针变量,写法是 FILE fp = NULL。
第三步 调用 fopen 传入文件路径和打开模式,把返回值赋值给 fp。
第四步 判断 fp 是否等于 NULL,如果等于 NULL 代表打开失败,要打印错误提示并且退出程序,防止后续对空指针操作造成崩溃。
第五步 文件打开成功之后,调用 fread fwrite fgetc fputc fscanf fprintf 这类函数,通过 fp 完成读写操作。
第六步 文件操作全部完成之后,调用 fclose (fp) 关闭文件,关闭之后操作系统会刷新缓冲区释放文件句柄,养成必写 fclose 的习惯,避免数据没有落盘。
第七步 关闭之后可以把 fp 置空,防止野指针被二次误用。
基础示例代码
include
int main()
{
FILE fp = NULL;
fp = fopen("test.txt", "w");
if(fp == NULL)
{
printf("fopen打开文件失败\n");
return -1;
}
fprintf(fp, "hello fopen\n");
fclose(fp);
return 0;
}
重点易错细节
第一 w 模式会直接清空旧文件,很多人本意是追加,错写成 w,原文件数据直接丢失,需要追加写入优先选择 a 或者 a+。
第二 r 模式不会创建文件,文件不存在直接返回 NULL,这个和 w 模式行为完全不同。
第三 文本模式和二进制模式差异,Windows 系统下文本模式会自动转换换行符,二进制模式不做转换,处理 exe 图片音频这类文件必须加 b,否则文件损坏。
第四 权限问题,目标文件夹只读或者当前用户没有读写权限,fopen 也会返回 NULL,不一定是文件名写错。
第五 多线程环境同一个 FILE 指针不要多线程同时读写,fopen 得到的流默认不是完全线程安全,需要额外加锁保护。
第六 长路径中文路径,部分旧版本编译器环境下中文路径 fopen 会失败,推荐使用英文路径测试。
总结 fopen 函数核心就是打开文件获取 FILE 指针,选择正确 mode 模式,强制判断空指针,操作结束调用 fclose,理解 r w a r+ w+ a + 以及带 b 二进制模式的行为差异,就可以掌握 fopen 绝大多数场景的用法。
【常见问题】
问题 1 fopen 函数打开失败返回什么值?
回答 1 fopen 函数打开失败的时候返回 NULL 空指针,代码必须判断这个返回值,否则后续读写会出现空指针异常,这是 fopen 函数最重要的安全检查步骤。
问题 2 fopen 的 w 模式会不会保留原来文件内容?
回答 2 fopen 使用 w 模式打开已经存在的文件,会直接清空原有全部内容,不会保留旧数据,如果想保留旧数据并且末尾追加,fopen 要选用 a 模式。
问题 3 fopen 和二进制打开模式 rb 有什么区别?
回答 3 fopen 普通 r 是文本模式,会自动处理换行转换,fopen 的 rb 是二进制只读模式,不做字符转换,读取图片二进制文件的时候 fopen 必须使用 rb,防止数据被修改损坏。
问题 4 fopen 打开文件之后为什么一定要调用 fclose?
回答 4 fopen 打开文件之后数据会保存在操作系统缓冲区,调用 fclose 才会把缓冲区数据写入磁盘,同时释放文件句柄,如果不调用 fclose,fopen 打开的文件可能出现数据丢失句柄泄漏。
【免责申明】
本内容为 C 语言 fopen 函数学习参考讲解,不同编译器操作系统对 fopen 的底层实现和异常行为存在差异,正式项目开发请参考对应平台官方手册。


