1. 打开和关闭文件
打开文件
在使用文件前必须成功打开相应的文件才能够进行后续的读写操作。C 语言标准库中提供了 fopen 函数用于打开文件。
使用 C 语言标准库对文件进行操作需要包含头文件 stdio.h。
fopen 函数
FILE *fopen(const char *pathname, const char *mode);
说明:
pathname参数是需要打开文件的路径(相对路径或决定路径)。mode参数用于控制文件的打开方式和操作权限。- 返回值是 FILE 类型的指针,用于对文件进行I/O 操作,我经常成之为文件流指针(stream)。成功则返回结构体地址,失败返回
NULL。 - fopen函数发生错误时会设置全变变量
errno的值。可以通过perror函数打印该值对应的错误信息。
FILE 是结构体类型别名,大致定义如下:
typedef struct {
// ... 结构体内的成员变量
} FILE;
在使用标准库函数对文件进行操作时,我们无需关心 FILE 结构体的成员变量有哪些。
mode 参数详解
模式
说明
"r" 或 "rt"从文件头位置读文本文件。
"r+" 或 "rt+"从文件头位置读/写文本文件。
"w" 或 "wt"从文件头位置写文本文件,没有文件则创建文件,文件存在则清空内容。
"w+" 或 "wt+"从文件头位置读/写文本文件,没有文件则创建文件,文件存在则清空内容。
"a" 或 "at"从文件头位置末尾写文本文件,没有文件则创建文件,文件存在则内容不变,在后面追加新内容。
"a+" 或 "at+"从文件头位置末尾读/写文本文件,没有文件则创建文件,文件存在则内容不变,在后面追加新内容。
上述 mode 参数的值都是文本文件模式对文件进行操作。文本文件的读写方式默认是 t(text),可以省略不写。当以二进制方式对文件进行操作时,mode 参数的值中需要添加字符 b(binary)。
如下表所示
文本模式
二进制模式
说明
"r" 或 "rt""rb"从文件头位置读文件。
"r+" 或 "rt+""rb+"从文件头位置读/写文件。
"w" 或 "wt""wb"从文件头位置写文件。
"w+" 或 "wt+""wb+"从文件头位置读/写文件。
"a" 或 "at""ab"从文件头位置末尾写文件(追加)。
"a+" 或 "at+""ab+"从文件头位置末尾读/写文件(追加)。
关闭文件
在文件使用完毕后必须进行关闭,否则可能浪费资源和数据丢失。使用标准库函数 fclose 可以关闭 使用 fopen 成功打开的文件。
fclose 函数
int fclose(FILE *stream);
说明:
- stream 参数是 fopen 成功打开文件后返回的文件结构体指针。
- 成功关闭则返回 0,失败返回 EOF(-1),同时设置错误号
errno。
示例:
尝试以文本文件只写的方式打开一个文件 myfile.txt,如果文件不存在则创建该文件并打开。
// filename: fopen_for_write.c
#include <stdio.h>
int main(int argc, char * argv[]) {
FILE * pfile = NULL; // 用于保存已经打开的文件
// 打开文件 myfile.txt
pfile = fopen("myfile.txt", "w");
if (NULL == pfile) {
// 根据全局变量 errno 错误号打印错误原因
perror("打开文件 myfile.txt");
return -1;
}
// ... 写入文件的内容(略)
// 关闭文件
fclose(pfile);
return 0;
}
编译和运行结果如下:
weimingze@mzstudio:~$ ls
fopen_for_write.c
weimingze@mzstudio:~$ gcc -o fopen_for_write fopen_for_write.c
weimingze@mzstudio:~$ ./fopen_for_write
weimingze@mzstudio:~$ ls
fopen_for_write fopen_for_write.c myfile.txt
weimingze@mzstudio:~$ ls -l myfile.txt
-rw-r--r-- 1 weimingze weimingze 0 12月 5 14:35 myfile.txt
从运行结果可知,开始文件夹内只有 fopen_for_write.c 编译后多了一个 fopen_for_write文件,程序运行后又创建了 myfile.txt,myfile.txt 文件的长度是 0 字节。
示例:
尝试以文本文件只读的方式打开文件 myfile.txt,如果失败则报错。
// filename: fopen_for_read.c
#include <stdio.h>
int main(int argc, char * argv[]) {
FILE * pfile = NULL; // 用于保存已经打开的文件
// 以只读方式打开文件 myfile.txt
pfile = fopen("myfile.txt", "r"); //<-- 注意此处是 "r"
if (NULL == pfile) {
// 根据全局变量 errno 错误号打印错误原因
perror("打开文件 myfile.txt");
return -1;
}
// ... 读取文件的内容(略)
// 关闭文件
fclose(pfile);
return 0;
}
编译和运行结果如下:
weimingze@mzstudio:~$ ls
fopen_for_read.c myfile.txt
weimingze@mzstudio:~$ gcc -o fopen_for_read fopen_for_read.c
weimingze@mzstudio:~$ ls
fopen_for_read fopen_for_read.c myfile.txt
weimingze@mzstudio:~$ ./fopen_for_read
weimingze@mzstudio:~$ rm myfile.txt # 删除文件 myfile.txt
weimingze@mzstudio:~$ ls
fopen_for_read fopen_for_read.c
weimingze@mzstudio:~$ ./fopen_for_read
打开文件 myfile.txt: No such file or directory
从运行结果可见,开始时存在文件 myfile.txt,程序运行不会有任何提示。当删除文件 myfile.txt 后再运行程序,则程序提示:No such file or directory。
实验:
写程序,使用循环创建 file1.txt、file2.txt、file3.txt、... file20.txt 等一共 20 个空的文件。