《小菜狗 C 语言入门 + 进阶笔记》目录:《小菜狗 C 语言入门 + 进阶笔记》(0)简介
1、文件操作流程
操作文件的正确流程为:打开文件 --> 读写文件 --> 关闭文件
。文件在进行读写操作之前要先打开,使用完毕要关闭
。
(1) 打开文件就是获取文件的有关信息
,例如文件名、文件状态、当前读写位置等,这些信息会被保存到一个 FILE 类型的结构体变量中
。
(2) 关闭文件就是断开与文件之间的联系,释放结构体变量,同时禁止再对该文件进行操作
。
(3) 文件有多种读写方式:
- 可以一个字符一个字符地读取;
- 也可以读取一整行;
- 还可以读取若干个字节。
(4) 文件的读写位置
也非常灵活,可以从文件开头
读取,也可以从中间位置
读取。
2、打开文件
操作文件之前必须先打开文件:
- 所谓“打开文件”,就是让程序和文件建立连接的过程。
- 打开文件之后,程序可以得到文件的相关信息,例如大小、类型、权限、创建者、更新时间等。
- 在后续读写文件的过程中,程序还可以记录当前读写到了哪个位置,下次可以在此基础上继续操作。
使用 <stdio.h> 头文件中的 fopen() 函数
来创建一个新的文件
或者打开一个已有的文件
。这个调用会初始化类型 FILE 的一个对象,类型 FILE 包含了所有用来控制流的必要的信息。
2.1、fopen 函数
下面是这个函数调用的原型:
FILE *fopen(const char *filename, const char *mode);
功能:
根据文件的名字和打开方式,打开⼀个文件。
参数:
filename
为文件名(包括文件路径),mode
为打开方式,它们都是字符串。
返回值(判断文件是否打开成功):
如果打开文件成功返回文件信息区的地址,如果打开失败返回 NULL,因为文件打开可能会失败,所有在调用完 fopen 函数后,⼀定要判断其返回值。
如下部分代码所示:
FILE *fp;
if( (fp = fopen("C:\\Users\\hwc\\Desktop\\demo.txt", "r")) == NULL ) {
printf("Fail to open file!\n");
exit(0); //退出程序(结束程序)
}
表示以“只读”方式打开当前目录下的 demo.txt 文件,并使 fp 指向该文件,这样就可以通过 fp 来操作 demo.txt 了。fp 通常被称为文件指针。
注意:代码中 demo.txt 文件是在 windows 的桌面上,如果是 linux 的环境,文件名就不一样了。比如是 /home/user/demo.txt。
2.2、打开方式(重要)
文件打开方式由 r、w、a、t、b、+ 六个字符拼成
,各字符的含义是:
- r (read):读
- w (write):写
- a (append):追加
- t (text):文本文件
- b (binary):二进制文件
- +:读和写
打开方式 mode 的值可以是下列值中的一个:
控制读写权限的字符串(必须指明) | |
---|---|
模式 | 描述 |
r | 打开一个已有的文本文件,允许读取文件。 |
w | 打开一个文本文件,允许写入文件。如果文件不存在,则会创建一个新文件。在这里,您的程序会从文件的开头写入内容。如果文件存在,则该会被截断为零长度,重新写入。 |
a | 打开一个文本文件,以追加模式写入文件。如果文件不存在,则会创建一个新文件。在这里,您的程序会在已有的文件内容中追加内容。 |
r+ | 打开一个文本文件,允许读写文件。 |
w+ | 打开一个文本文件,允许读写文件。如果文件已存在,则文件会被截断为零长度,如果文件不存在,则会创建一个新文件。 |
a+ | 打开一个文本文件,允许读写文件。如果文件不存在,则会创建一个新文件。读取会从文件的开头开始,写入则只能是追加模式。 |
控制读写方式的字符串(可以不写) | |
模式 | 描述 |
t | 文本文件。如果不写,默认就是 t。 |
b | 二进制文件。 |
如果处理的是二进制文件,则需使用下面的访问模式来取代上面的访问模式
:
"rb", "wb", "ab", "rb+", "r+b", "wb+", "w+b", "ab+", "a+b"
就会变成以下这样:
控制读写权限的字符串(必须指明) | |
---|---|
模式 | 描述 |
rb | 打开一个已有的二进制文件,允许读取二进制文件。 |
wb | 打开一个二进制文件,允许写入文件。如果二进制文件不存在,则会创建一个新二进制文件。在这里,您的程序会从文件的开头写入内容。如果文件存在,则该会被截断为零长度,重新写入。 |
ab | 打开一个二进制文件,以追加模式写入文件。如果文件不存在,则会创建一个新文件。在这里,您的程序会在已有的文件内容中追加内容。 |
rb+ | 打开一个二进制文件,允许读写文件。 |
wb+ | 打开一个二进制文件,允许读写文件。如果文件已存在,则文件会被截断为零长度,如果文件不存在,则会创建一个新文件。 |
ab+ | 打开一个二进制文件,允许读写文件。如果文件不存在,则会创建一个新文件。读取会从文件的开头开始,写入则只能是追加模式。 |
控制读写方式的字符串(可以不写) | |
模式 | 描述 |
t | 文本文件。如果不写,默认就是 t。 |
b | 二进制文件。 |
2.3、fopen 函数的注意点
FILE *fopen(const char * filename, const char * mode);
(1) 该函数可能执行失败,返回值是 NULL
,安全起见必须对返回值进行合法性判断;
(2) 模式的合法性说明:
读写权限(r、w、a、+)
和读写方式(t、b)
可以组合使用,但是必须将读写方式放在读写权限的中间或者尾部
(换句话说,不能将读写方式放在读写权限的开头)。
例如:
- 将读写方式放在读写权限的末尾:“rb”、“wt”、“ab”、“r+b”、“w+t”、“a+t”;
- 将读写方式放在读写权限的中间:“rb+”、“wt+”、“ab+”;
- 不能用大写,只能是小写**。**
(3) 模式 w 的自动新建文件是有条件的
,只有对应的路径存在(即文件所在的文件夹存在),文件不存在才会新建,否则是不会新建的,返回 NULL。
(4) r+ 和 w+ 看似一样,都是读写其实还是有几点区别的:
- 模式 r+ 找不到文件不会自动新建,而 w+ 会;
- 模式 r+ 打开文件后,不会清除文件原数据,若直接开始写入,只会从起始位置开始进行覆盖,而 w+ 会直接清零后,再开始读写;
3、关闭文件
关闭文件使用 fclose( ) 函数。
函数的原型如下:
int fclose(FILE *fp);
功能:
关闭与参数 stream 关联的文件流,在关闭文件之前会刷新缓冲区。
参数:
stream:这是指向 FILE 对象的指针,该 FILE 对象指定了要被关闭的流。
返回值:
如果流成功关闭,则该方法返回零。如果失败,则返回 EOF。
这个函数实际上,会清空缓冲区中的数据,关闭文件,并释放用于该文件的所有内存。EOF 是一个定义在头文件 stdio.h 中的常量。
4、打开关闭文件举例
#include <stdio.h>
#include <stdlib.h>
#define N 10
int main()
{
FILE *fp;
char str[N + 1];
//判断文件是否打开失败
if ( (fp = fopen("C:\\Users\\hwc\\Desktop\\demo.txt", "rt")) == NULL ) {
puts("Fail to open file!");
exit(0);
}
//循环读取文件的每一行数据
while( fgets(str, N, fp) != NULL ) {
printf("%s", str);
}
//操作结束后关闭文件
fclose(fp);
return 0;
}
5、编译告警
有些编译环境中会提示使用 fopen 函数不安全
。
错误提示:
错误 C4996 ‘fopen’: This function or variable may be unsafe. Consider using fopen_s instead. To disable deprecation, use _CRT_SECURE_NO_WARNINGS. See online help for details.
解决办法:在代码首行写上
:
#define _CRT_SECURE_NO_WARNINGS
定义宏忽略警告,即可忽略安全警告。
补充
当 fopen 不安全,推荐使用 fopen_s 代替。
fopen_s 和 fopen 的区别在于:
errno_t fopen_s( FILE** pFile, const char *filename, const char *mode );
FILE *fopen(const char *filename, const char *mode)
fopen_s 有三个参数,第一个参数是二级指针,用于存放文件流指针地址,其他的同 fopen 一致
。
也就是说,用 fopen 需要这么写:
FILE* fp = NULL;
fp = fopen("\\123.txt", "w+");
而如果用 fopen_s:
FILE* fp = NULL;
fopen_s(&fp, "\\123.txt", "w+");
就可以了。
《小菜狗 Linux 操作系统快速入门笔记》目录:
《小菜狗 Linux 操作系统快速入门笔记》(01.0)文章导航目录【实时更新】
每日一更!
公众号、CSDN等博客:小菜狗编程笔记
谢谢点赞关注哈!目前在飞书持续优化更新~
**`日更较慢有需要完整笔记请私我,C/C++/数据结构-算法/单片机51-STM32-GD32-ESP32/嵌入式/Linux操作系统/uboot/Linux内核-驱动-应用/硬件入门-PCB-layout/Python/后期小程序和机器学习!