fopen
fopen 函数用于打开一个文件,并返回一个指向 FILE 结构体的指针,这个指针在后续的所有文件操作(如 fread, fwrite, fprintf, fscanf 等)中都扮演着“文件句柄”的角色。

(图片来源网络,侵删)
函数原型
#include <stdio.h> FILE *fopen(const char *pathname, const char *mode);
-
参数:
pathname: 一个字符串,表示你要打开的文件的路径,可以是相对路径(如"data.txt")或绝对路径(如"/home/user/data.txt")。mode: 一个字符串,规定了文件的打开方式,这是最重要的部分,决定了你是读取、写入还是追加等内容。
-
返回值:
- 成功:返回一个指向
FILE结构体的指针。 - 失败:返回
NULL指针。每次调用fopen后都必须检查返回值是否为NULL,以判断文件是否成功打开。
- 成功:返回一个指向
文件打开模式 (mode)
mode 参数决定了文件如何被打开,以下是常用模式的详细说明:
| 模式 | 含义 | 如果文件不存在 | 如果文件存在 | 文件指针初始位置 |
|---|---|---|---|---|
"r" |
只读 | 出错 (返回 NULL) | 打开成功 | 文件开头 |
"w" |
只写 | 创建新文件 | 清空文件内容 | 文件开头 |
"a" |
追加 | 创建新文件 | 打开成功 | 文件末尾 |
"r+" |
读写 | 出错 (返回 NULL) | 打开成功 | 文件开头 |
"w+" |
读写 | 创建新文件 | 清空文件内容 | 文件开头 |
"a+" |
读写 | 创建新文件 | 打开成功 | 文件末尾 |
模式组合(添加 b)
"b": 在模式字符串末尾添加b,表示以二进制模式打开文件。"rb","wb+","ab"。- 在 Linux/Unix 系统中,文本模式和二进制模式没有区别(因为换行符就是
\n),但在 Windows 系统上,文本模式会自动将\n转换为\r\n,为了代码的可移植性,处理非文本文件(如图片、可执行文件)时,强烈推荐使用二进制模式。
错误处理
fopen 失败最常见的原因是:

(图片来源网络,侵删)
- 文件不存在:当你以
"r"或"r+"模式打开一个不存在的文件时。 - 权限不足:你没有权限读取或写入指定的文件路径。
- 路径无效:你提供的路径不存在或格式错误。
最佳实践:永远检查 fopen 的返回值。
FILE *fp = fopen("my_file.txt", "r");
if (fp == NULL) {
// 文件打开失败,需要处理错误
perror("fopen failed"); // 打印详细的错误信息到 stderr
return -1; // 或 exit(EXIT_FAILURE);
}
perror()函数是一个非常方便的工具,它会打印你提供的字符串(如"fopen failed"),后面会跟上系统生成的具体错误原因(如No such file or directory)。
完整示例
下面是一个完整的 C 程序,演示了如何:
- 以写入模式 (
"w") 创建并写入文件。 - 以读取模式 (
"r") 读取文件内容。 - 以追加模式 (
"a") 向文件添加新内容。 - 正确处理所有错误和资源释放。
#include <stdio.h>
#include <stdlib.h> // 用于 exit 函数
int main() {
FILE *fp;
char filename[] = "example.txt";
char content[] = "Hello, Linux C Programming!\n";
char append_content[] = "This is an appended line.\n";
char read_buffer[256];
// --- 1. 写入模式 ("w") ---
// 如果文件已存在,其内容将被清空。
fp = fopen(filename, "w");
if (fp == NULL) {
perror("Error opening file for writing");
return EXIT_FAILURE;
}
// 写入字符串
fprintf(fp, "%s", content);
printf("Content written to %s\n", filename);
// 关闭文件
fclose(fp);
// --- 2. 读取模式 ("r") ---
fp = fopen(filename, "r");
if (fp == NULL) {
perror("Error opening file for reading");
return EXIT_FAILURE;
}
printf("\n--- Reading file content ---\n");
// 使用 fgets 逐行读取
while (fgets(read_buffer, sizeof(read_buffer), fp) != NULL) {
printf("%s", read_buffer);
}
// 关闭文件
fclose(fp);
// --- 3. 追加模式 ("a") ---
fp = fopen(filename, "a");
if (fp == NULL) {
perror("Error opening file for appending");
return EXIT_FAILURE;
}
// 追加字符串
fprintf(fp, "%s", append_content);
printf("\nContent appended to %s\n", filename);
// 关闭文件
fclose(fp);
// --- 4. 再次读取以验证追加 ---
fp = fopen(filename, "r");
if (fp == NULL) {
perror("Error opening file for reading again");
return EXIT_FAILURE;
}
printf("\n--- Reading file content after append ---\n");
// 读取文件指针到开头,以便重新读取
rewind(fp);
while (fgets(read_buffer, sizeof(read_buffer), fp) != NULL) {
printf("%s", read_buffer);
}
// 关闭文件
fclose(fp);
return EXIT_SUCCESS;
}
如何编译和运行
- 将上述代码保存为
file_operations.c。 - 打开终端,使用
gcc编译:gcc file_operations.c -o file_operations
- 运行生成的可执行文件:
./file_operations
预期输出
Content written to example.txt
--- Reading file content ---
Hello, Linux C Programming!
Content appended to example.txt
--- Reading file content after append ---
Hello, Linux C Programming!
This is an appended line.
你会在当前目录下看到一个名为 example.txt 的文件,内容与输出一致。
- 包含头文件:
#include <stdio.h> - 打开文件:
FILE *fp = fopen("path/to/file", "mode"); - 检查错误: 必须检查
fp是否为NULL,使用perror()打印错误信息。 - 操作文件: 使用
fprintf,fscanf,fread,fwrite,fgets,fputs等函数通过fp指针进行读写。 - 关闭文件: 必须调用
fclose(fp)来释放系统资源,这是一个好习惯,即使程序退出时系统会自动回收,但在长时间运行的程序中不关闭文件会导致资源泄漏。 - 模式选择: 根据你的需求(读、写、创建、追加)选择正确的模式。
- 二进制模式: 处理非文本文件时,使用
"rb","wb"等模式以保证可移植性。

(图片来源网络,侵删)
