【C语言】文件操作详解1(文件的打开与关闭)

【C语言】文件操作详解1(文件的打开与关闭)

前言:
本期开始详解文件操作,由于文章过长,所以分了两篇文
若内容对大家有所帮助,可以收藏慢慢看,感谢大家支持
谢谢大家 ! ! !

一、文件

1.文件是什么?

文件包括什么呢?

文件的分类(从文件功能角度分类):
程序文件:

1.源程序文件 (以 .c 为后缀)

2.目标文件 (Windows环境以 .obj 为后缀)

3.可执行程序 (Windows环境下以 .exe 为后缀)
数据文件:
程序运行时读写的数据存储文件

(比如老师点名的电子花名册)

文件的文件名是什么呢?

一个文件的文件名:
文件路径 + 文件名主干 + 文件后缀
例如一文件名:
D:\学校\C语言\MINE\x64\Release\MINE.exe
文件路径是 D:\学校\C语言\MINE\x64\Release\
文件名主干是 MINE
文件后缀是 .exe

2.文件的作用

内存数据易失性:

程序运行时数据存储在内存中,程序退出后内存被回收,数据就会丢失

例如变量在程序结束后无法保留。
持久化保存方案:

使用文件可以将数据存储在硬盘上,实现数据的持久化保存,下次运行程序时仍可读取之前的数据。
所以,文件可将数据进行持久化的保存

在以前,我们都在电脑终端上输出信息

如图,这就是终端:

也可以把信息输入到磁盘上,当需要的时候再从磁盘上吧数据读取使用

但怎么输入又是一个问题了

二、数据文件

数据文件可以分为二进制文件文本文件
二进制文件:
将内存中的二进制数据不加转换直接输出到外存文件中
适用于存储程序运行时产生的中间数据或需要高效存储的场景
文本文件:

在存储前进行转换,将数据转换为ASCII码形式再存储的文件
适用于配置文件、日志文件等需要人工阅读的场景
字符一律以ASCII码形式存储,而数值型数据都可以

给大家举一个例子吧,以10000输出到磁盘(文件)为例

这里用图解给大家讲解:

有了这张图,想必大家已经知道了数据文件怎么存储了
接下来就是本文的核心知识------如何打开和关闭文件

三、文件的打开与关闭(本章重点!!!)

1.流和标准流

  • 流是什么?

我们程序的数据需要输出到各种外部设备,也需要从外部设备获取数据
而为了方便对各种外部设备进行操作,我们就抽象出了 " 流 "这个概念
要想向流里 写 / 读 数据
都是要打开流,在进行操作( 写 / 读 ),最后关闭流

如图(图解):

  • 标准流是什么?

C程序启动时,默认打开三个流
这些流被称作标准流:

stdin--标准输入流(从键盘输入)
(scanf函数从此读取数据)
stdout--标准输出流(从屏幕输出)
(printf函数向此输出数据)
stderr--标准错误流(从屏幕输出)

2.文件指针

每个被使用的文件都在内存中开辟了一个文件信息区,其中有许多文件的信息,这些信息被保存在一个结构体中

例如:

标准流对应的文件信息保存在FILE结构体中
包含文件名、状态、当前位置等信息
该结构体类型是由系统声明决定的,取名为FILE

(系统声明在头文件 <stdio.h> 中)

而文件指针 ( FILE * ) 是管理流的关键概念,其指向内存中的文件信息区
通过文件指针变量,能够间接找到与其关联的文件

文件指针的定义:
FILE * pf ;//其中 pf 就是一个文件指针变量

3.文件的打开(fopen函数)

文件开关的标准流程:

  1. 打开文件(创建文件信息区)
  2. 读写文件(通过文件指针操作)
  3. 关闭文件(释放资源)

关于fopen函数小编也是在c++官网上查询的,大家也可以自行查看
https://legacy.cplusplus.com/reference/cstdio/fopen/?kw=fopen

(1)fopen简介

在C语言中,我们用 fopen 打开文件
用于打开文件,建立程序与硬盘文件之间的数据通道

fopen 语法:
FILE * fopen ( const char * filename, const char * mode );
(返回值要用FILE *类型来接收)
filename是要打开的文件名,传入一个字符串指针,指定要打开的文件名称
mode是文件的打开方式,指定文件的访问模式,如"r"表示只读,"w"表示写入

(2)filename(要打开的文件名)

filename是要打开的文件名,需要传入该文件的具体路径
例如:
D:\学校\C语言\QwQ\QwQ\test.txt
打开文件完整代码:
FILE * pf = fopen( "D:\学校\C语言\QwQ\QwQ\test.txt" , " w " ) ;
这样就可以打开电脑中的文件 test.txt
但是,有时也不需要传入具体地址
若文件就在程序文件内时,只需写文件名

如下图,源文件和要打开的文件在同一文件中时

打开文件就只需写如下代码:
FILE * pf = fopen( "test.txt" , " w " ) ;//只需写文件名

(3)mode(文件打开方式)

在参数文件名的后面,就是打开方式了

打开方式有很多,下面放了一张图表,包含了所有的打开方式
本篇就先讲最基础的三种方式------"r"、"w"、"a".

首先,我们要知道什么是 " 读 " ,什么是 " 写 "
" 读 "输入数据,将数据从磁盘(文件)中输入到内存中存储
" 写 "输出数据,将数据从内存中输出到磁盘(文件)中存储

  • " r "(只读)

为了输出数据,打开一个已经存在的文本文件,且不会修改原文件
(若文件不存在,会报错)

代码演示:(文本文件存在,不报错)

c 复制代码
 #include<stdio.h>

int main()
{
    FILE* pf = fopen("test.txt", "r");

    return 0;
}

这样,文件就被打开了,后续就可以进行读取操作了(下期讲)

代码演示:(文本文件不存在,报错)

c 复制代码
#include<stdio.h>

int main()
{
    FILE* pf = fopen("test.txt1", "r");

    return 0;
}

运行结果:(报错)

这里可以看到,代码报错了
原因就是电脑里没有这个文件,那自然读取不了了

  • " w "(只写)

为了输出数据,打开一个文本文件,并清空原文件内容
(若不存在,会新建一个文件)

代码演示:(文件存在)
现在我们先在源文件旁新建一个文件,并输入一些内容

输入后再用如下代码打开文件

c 复制代码
#include<stdio.h>

int main()
{
    FILE* pf = fopen("test.txt", "w");

    return 0;
}

代码运行完后再点开这个文件

我们可以发现,原来我们输入的数据不见了,文件内容被清空了
这就是以 " w " 方式打开文件的特点------会清空原文件的内容

代码演示:(文件不存在)
现在我们不新建文件,但用 " w " 方式打开

c 复制代码
#include<stdio.h>

int main()
{
    FILE* pf = fopen("test.txt", "w");

    return 0;
}

运行前:


运行后:

这里我们可以发现,系统自动给我们新建了一个文件,文件名就是参数
当文件不存在时,就会新建一个文件

  • " a "(追加)

向文本文件尾部添加数据,且不会修改原文件
(若文件不存在,会新建一个文件)

代码演示:(文件存在)
现在我们先在源文件旁新建一个文件,并输入一些内容

再用代码进行追加(这里先用到输出操作,下期会讲):

c 复制代码
 #include<stdio.h>

int main()
{
    FILE* pf = fopen("test.txt", "a");
    fputs("efgh",pf);

    return 0;
}

运行结果:(追加)

可以看到,文本文件追加了新的字符串
但若文件不存在,就直接创建一个文件再输出

最后总结一下打开方式:
" r "(只读)
为了输出数据,打开一个已经存在的文本文件,且不会修改原文件
(若文件不存在,会报错)
" w "(只写)
为了输出数据,打开一个文本文件,并清空原文件内容
(若不存在,会新建一个文件)
" a "(追加)
向文本文件尾部添加数据,且不会修改原文件
(若文件不存在,会新建一个文件)

在以后的学习中
我也会一 一给大家介绍其他的文件打开方式哦,尽情期待
当然,如果还想了解更多就可以去c++官网找找

https://legacy.cplusplus.com/reference/cstdio/fopen/?kw=fopen

(3)fopen的返回值

fopen的返回类型是FILE *
若文件打开成功,返回的是有效指针
若文件打开失败,返回的是NULL(空指针)
所以,在进行操作前,要确保文件打开成功

为确保文件打开成功,可打开文件后写入一个 if 语句判断fopen返回值
若为NULL(空指针),则说明文件打开失败
这时我们还可以用 perror 函数打印出错误信息

perror("fopen");

(关于perror函数就不过多介绍啦,大家可去此处查询)
https://legacy.cplusplus.com/reference/cstdio/perror/?kw=perror

代码演示:

c 复制代码
#include<stdio.h>

int main()
{
    FILE* pf = fopen("test.txt", "r");
    if (pf == NULL)
    {
        perror("fopen");
        //打印出错误信息
        return 1;
        //返回状态码 1 表示异常退出
    }

    return 0;
}

运行结果:

这里翻译过来也是没有找到该文件
perror 函数还是很有用的,可以帮助我们打印出错误信息

4.文件的关闭(fclose函数)

(1)fclose函数简介

fclose 语法:
int fclose ( FILE * stream );
stream表示要关闭的文件的文件指针
例如:
fclose(pf);

这样,pf所指的文件就被关闭了

(2)fclose函数注意事项

虽然fclose函数很简单,但还是有些注意事项:
fclose(pf); //此处pf为野指针
当你关闭了文件时,其指针pf就会变为野指针
故关闭文件文件后,必须立即置为NULL

代码演示:

c 复制代码
#include<stdio.h>

int main()
{
    FILE* pf = fopen("test.txt", "r");
    if (pf == NULL)
    {
        perror("fopen");
        //打印出错误信息
        return 0;
        //返回状态码 1 表示异常退出
    }
    fclose(pf);
    pf = NULL;//置为NULL空指针

    return 0;
}

这样就不会有安全问题啦
大家写代码的时候也要严谨一点哦

结语

本期资料来自于:

https://legacy.cplusplus.com/

OK,本期的文件操作详解到这里就结束了
由于文章过长,所以分了两篇文,下期我们讲解文件的读写操作
若内容对大家有所帮助,可以收藏慢慢看,感谢大家支持
本文有若有不足之处,希望各位兄弟们能给出宝贵的意见。谢谢大家!!!
新人,本期制作不易希望各位兄弟们能动动小手,三连走一走!!!
支持一下(三连必回QwQ)

相关推荐
j***12151 小时前
计算机体系结构期末复习3:GPU架构及控制流问题
java·开发语言·架构
聊天QQ:4877392781 小时前
哈里斯鹰算法的改进:融合自然与光学智慧的优化探索
数据结构
wbs_scy1 小时前
C++ :手写 List 容器实战(从双向链表原理到完整功能落地,附源码与测试验证)
数据结构·链表
资深web全栈开发1 小时前
[特殊字符] LeetCode 2141:如何让 N 台电脑续航最久?——“二分答案“套路一文讲透
算法·leetcode
还下着雨ZG1 小时前
VC6.0:Window平台专属的C/C++集成开发环境(IDE)
c语言·c++·ide
木婉清fresh1 小时前
测开python高频面试精选100题
开发语言·python·面试
缘三水1 小时前
【C语言】9.操作符详解(上)
c语言·开发语言·新人首发
刃神太酷啦1 小时前
C++的IO流和C++的类型转换----《Hello C++ Wrold!》(29)--(C/C++)
java·c语言·开发语言·c++·qt·算法·leetcode
不想写笔记1 小时前
C语言 函数
c语言·笔记