《小菜狗 C 语言入门 + 进阶笔记》(41)文件基本操作 - 打开关闭文件【文件编程中最经常使用的操作!】


《小菜狗 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/后期小程序和机器学习!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

小菜狗编程笔记

你的鼓励将是我最大的动力!

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值