C语言文件操作的基础应用(超详细)

本文详细介绍了C语言中的文件操作方法,包括文件的打开与关闭、顺序读写与随机读写等核心概念和技术要点。

目录

前言

什么是文件

数据文件

程序文件

文件指针

fopen

文件名

 打开方式

fclose

 文件的读写

顺序读写

fputc

fgetc

 fputs

 fgets

 fprintf和fscanf

fwrite

fread

文件的随机读写

fseek

 rewind

ftell

文件的打开方式

w

 r

a

wb,rb,ab

w+ r+ a+

总结


前言

在以前我们写的代码,无论运行时在内存中存储了多少的数据,当我们将执行文件关闭,再次打开后所存的数据也都会消失不见。试想当下的软件跟应用可有不能进行存储的功能吗?所以将我们所写的代码导入文件之中,便显得相当重要。于是就有了今天所讲的文件操作。这样我们就可以将数据直接存放在电脑的硬盘上,做到数据的持久化。

什么是文件

一般说的文件包括两种:数据文件跟程序文件。

数据文件

包括源程序文件(后缀为.c),目标文件(windows环境后缀为.obj),可执行程序(windows环境
后缀为.exe)。

程序文件

文件的内容不一定是程序,而是程序运行时读写的数据,比如程序运行需要从中读取数据的文件,
或者输出内容的文件。

文件指针

每个被使用的文件都在内存中开辟了一个相应的文件信息区,用来存放文件的相关信息(如文件的名字,文件状态及文件当前的位置等)。这些信息是保存在一个结构体变量中的。该结构体类型是有系统声明的,取名 FILE 

在VS2022中 FILE 的定义是这样的:

 而在VS2013则是如此:

 可见不同的编译器下 FILE 类型包含的内容虽然有些许不同但还是相同的使用方法,于操作者而言并不需要了解太多具体细节。

fopen

如果说 malloc 跟 calloc 是动态内存存在的基础,那文件操作失去了 fopen 就失去了操作的基础

在Cplusplus上进行查找。

 我们知道了其包含在 stdio.h 里面返回一个 FILE* 类型的数据,需要传入的参数有两个,一个是 const char* 类型的文件名,第二个是文件的打开方式。同时两者都代表的是字符串所以在使用的时候一定要注意双引号的使用。

文件名

我们先来讲第一个参数,仔细看关于这个参数的说明,这个字符串包含了要打开字符串的名字,如果系统支持的话可以写上文件的整个路径否则默认在当下文件夹内查询。在文件名后还要加上文件格式否则会出现文件识别错误或是创建出的文件的格式并不是我们想要的。所以在编写代码是时候需要十分注意。

 打开方式

文件的打开方式有多种:如只读的 只写的 用于追加数据的 ,以及读写的 r+ w+ 和 a+ 还有打开二进制文件的 rb wb 以及 ab 。甚至还有打开二进制进行读写的 rb+ wb+ ab+ 

文件使用方式含义如果指定文件不存在
“r”(只读)为了输入数据,打开一个已经存在的文本文件出错
“w”(只写)为了输出数据,打开一个文本文件建立一个新的文件
“a”(追加)向文本文件尾添加数据建立一个新的文件
“rb”(只读)为了输入数据,打开一个二进制文件出错
“wb”(只写)为了输出数据,打开一个二进制文件建立一个新的文件
“ab”(追加)向一个二进制文件尾添加数据出错
“r+”(读写)为了读和写,打开一个文本文件出错
“w+”(读写)为了读和写,建议一个新的文件建立一个新的文件
“a+”(读写)打开一个文件,在文件尾进行读写建立一个新的文件
“rb+”(读写)为了读和写打开一个二进制文件出错
“wb+”(读写)为了读和写,新建一个新的二进制文件建立一个新的文件
“ab+”(读写)打开一个二进制文件,在文件尾进行读和写建立一个新的文件

具体打开方式的区别我们留着后面讲。但是值得注意的一件事是用含 或 ab 打开方式如果查询不到指定文件则会返回一个空指针。为了避免出现错误,我们必须对 fopen 的返回值进行检查,如果正常才能让函数继续进行。

fclose

作用相当于动态内存中的 free ,只需传入前面打开文件时接收的指针用于关闭文件。与 free 相似关闭文件后前面 FILE* 类型的指针就变成了野指针,所以我们还需要讲该指针置空才能保证在往后的程序之中不会出现错误。

 

 文件的读写

打开文件后我们需要想要将数据从内存输出到文件或是从文件将数据输入进内存,都需要使用特定的库函数来实现。同时对于文件的读写还分作顺序读写跟随机读写。

顺序读写

fputc

作为一个用于将数据写入文件的函数,fputc需要传递的参数是要写入的字符以及目标文件的文件指针。写入成功则返回所写的字符,若发生错误则返回EOF。同时会使文件指针加一,指向下一个区域。

根据语法,我们打出了这样的程序,打开一个叫 test 格式为 txt 的文件后将一个字符 输出到文件上。

  

将程序运行之后,由于没有这个文件所以在当下文件夹自动建立了一个叫 test 的文本文件。

 打开这个文件后我们可以发现里面写入的就是 。说明我们的代码并没有出错,这个库函数确实能够将我们想要的数据输入到文件之中。

 同时根据其每次输入都会移动文件指针的特性,我们还可以这样子写,就完成了26个字符的输出。 

fgetc

该函数为字符输入函数,需要传入一个 FILE* 的类型的指针之后返回一个整型,该整型为所读字符所代表的 ASCII 码值,若是读取失败则返回 EOF 

 每次读取成功后文件指针都会往后移动一位,使得下次读取的便是下一个字符。

由于该函数一次只能读取一个字符所以即便我们后面还有很多内容也只能读取第一个字符。

 根据其特性,只要进行多次读取就可以将文件内的全部内容读出。

 fputs

fputs为文本行输入的函数,输入一个字符串并将其写入文件中。

直到遇到 \0 才结束读取,即便遇到 \n 也会继续读取并将文本数据换行。输出成功则会返回一个非 值。

 fgets

 fgets 与 fput 就是一对,一个是输入一个是输出且目标都是字符串,不过 gets 需要传入一个参数来表示一共需要读取多少个字符。并且读到 \n 和 \0 会停止读取,同时将 \n 复制到读出的字符串中

 所以若将之前输入进去的数据再打印出来,便只会截至到\n而停止。

 

 可以看到fgets还会将 \0 一并拷贝到目标数组之中,所以实际上读取到的字符数会比我们传入的那个参数要少 。并且读取成功后返回指向目标字符串的指针。

 fprintf和fscanf

二者用于格式化的输入和输出,语法跟其兄弟printf与scanf相似根据需要的数据类型及数量进行选择。用于多种格式的输入输出。 

如此便可以输出一个结构体中数据类型不同的多个参数。而且该函数会返回成功输出的项目数。

 与 scanf 相似记得第一个参数是文件指针,其他用法与scanf相同。如此操作后我们便实现将文件中的数据输入到我们定义的一个结构体之中。

fwrite

 fwrite 可以将我们想要的内容用二进制的形式输出在文件之中。 ptr 为指向要输出值的指针, size 为输出值的大小单位为字节, count 为输出的数量。成功则返回成功写入的元素总数。

还记得前面提到的 wb 是用于写入二进制的数据,所以这里也需要使用 wb 作为文件的打开方式。

这样子我们便成功将数据以二进制的形式写入文本,但是直接观察文本我们并没有看到有什么太大的变化,但是我们需要知道的是,记事本并不能识别二进制文件,于是他只能反应出他大致能识别出的文件。若我们用二进制的形式再将数据从文件中输入到内存中,我们会发现结果仍然是一样的。

fread

这就是我们从文件中读取二进制时所要用到的函数,内含的参数与 fwrite 类似。

 以同样的方式再打一串代码,我们可以观察到输出的结果与我们上一步所输入的数据是一样的。

 我们可以肯定的是,确实是有数据写入文件中,只不过通过记事本我们只能看到部分或是乱码。但是再次以二进制读取后输出的结果并无二致。

文件的随机读写

讲完了顺序读写,现在来讲随机读写。虽然它的名字叫随机读写,但是它并非真的在随机的位置进行读写,而是有一定规则的。

fseek

其需要的参数有三个,第一个是文件指针,第二个是从原点的偏移数,最后一个是原点的设定,关于原点的设定我们有三个选项,SEEK_SET代表的是设置为文件的开头,SEEK_END代表的是设置为文件的结尾,SEEK_CUR代表的是设置为当前文件指针的位置。同时偏移数可以是正数也可以是负数,若从文件开头开始则正向偏移,若从结尾开始则需要用负数进行反向偏移。如果成功,函数将返回零。否则,它将返回非零值。即变更当前文件指针的位置。

 rewind

 该函数只需要传入目标文件指针就能使文件指针回到初始位置。

ftell

 ftell 会用返回值告诉你文件指针相当于起始位置的偏移量。若失败,将返回-1L。

文件的打开方式

w

 w 代表的是只写不读,若找不到该文件则会创建一个新文件,同时在每次打开文件时都会将原文件的内容清空等待重新写入。因此普通写入不会造成问题,若是打开方式为 但实际进行的是读取的操作,最后不仅什么都没读到,更是原文件给清空了,更加得不偿失。

 r

代表的是只读不写,若是找不到该文件则会返回空指针,这个规律对于每个带 的打开方式都适用。

 

 然而文本的数据并没有发生变化。因此使用r打开文件并不会将文件里面的数据清除,但也做不到对数据进行追加。

a

a打开方式是向文本文件尾添加数据,若查找不到文件则会建立一个新的文件,作用与w类似但不会清除原文件内的数据。

wb,rb,ab

都表示打开一个二进制的文件,但查找不到指定文件的反应有所不同。

“rb”(只读)为了输入数据,打开一个二进制文件出错
“wb”(只写)为了输出数据,打开一个二进制文件建立一个新的文件
“ab”(追加)向一个二进制文件尾添加数据出错

w+ r+ a+

可读可写,可以在一个流程之中同时做到写入并读取,简便了读取的方式,但是未找到该文件时也有不同的情况。

“r+”(读写)为了读和写,打开一个文本文件出错
“w+”(读写)为了读和写,建议一个新的文件建立一个新的文件
“a+”(读写)打开一个文件,在文件尾进行读写建立一个新的文件

总结

fopen跟fclose在文件操作中起到地基的作用,在此基础上才能使用文件操作函数才可以对数据进行输入输出处理,关于打开方式的选择也大有讲究,什么时候选择什么方式显得格外重要。因此理清其不同的部分是能够完善使用的关键。同时需要结合顺序读写跟随机读写使文件操作更加灵活。

如果喜欢本篇文章就留下个赞吧,也欢迎大家在评论区留言讨论,谢谢大家。

评论 18
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

LinAlpaca

你的鼓励将是我创作的最大动力

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

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

打赏作者

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

抵扣说明:

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

余额充值