C语言文件操作

目录

一、关于文件

1、文件的分类

2、文件名

二、文件相关知识

1、文件指针

2、文件的打开/关闭

"r"示范样例

"w"示范样例

3、文件的顺序读写

相关函数:

fgetc

fputc

fgets

fputs

fscanf

fprintf

fread

fwrite

sprintf

sscanf 

4、文件的随机读取

fseek

ftell

rewind

5、文本文件和二进制文件

6、文件读取结束判定


一、关于文件

1、文件的分类

使用文件可以做到将数据直接存放到电脑的硬盘上,做到了数据的持久化

而文件又分为程序文件和数据文件

程序文件:源程序文件(后缀为.c/.cpp)目标文件(后缀为.obj)可执行程序(后缀为.exe)

数据文件:文件的内容是程序读写的数据,例如程序运行需要从中读取数据的文件,或是输出内容的文件


2、文件名

一个文件的文件名包含三部分:

文件路径 + 文件名主干 + 文件后缀

例如:D:\vs2019code\test.c

其中不同的颜色就代表不同的部分


二、文件相关知识

1、文件指针

每个被使用的文件都会在内存中开辟一个相应的文件信息区,用于存放文件的相关信息(名称、状态、存储位置....)

这些信息是保存在一个结构体变量中的,该结构体变量是有系统声明的,取名为FILE

当我们打开一个文件时,系统都会根据文件情况自动创建一个FILE结构的变量,填充信息

所以我们可以创建文件指针变量为FILE*

如果定义FILE* pf,则pf是一个指向FILE类型的指针变量,从而可以使pf指向某个文件的文件信息区,进而通过文件信息区的信息可以访问该文件

也就是说通过文件指针变量能够找到与它关联的文件

2、文件的打开/关闭

我们在使用前应打开文件,使用完毕后应关闭文件

打开文件是用fopen

fopen的返回值是FILE*

返回值是一个指针,但是如果遇到一个错误,则会返回空指针

fopen的第一个参数filename,指需要打开的文件名(这里注意:如果与当前的源文件不在一个路径下,也可以写入创建的文件路径)

fopen的第二个参数mode,指打开文件的方式

其中mode有以下几种方式:

"r":只读文件,如果文件不存在,则出错

"w":只写文件,如果文件不存在,则建立一个新文件,如果给的文件已经存在,则该文件会被销毁

"a":追加文件,如果文件不存在,则建立一个新文件

"rb":二进制只读,如果文件不存在,则出错

"wb":二进制只写,如果文件不存在,则建立一个新文件

"ab":二进制追加,如果文件不存在,则出错 

关闭文件是用fclose

fclose的参数就是一个FILE*的指针,所以关闭文件时直接传入文件指针即可


"r"示范样例

我们创建了一个testfile.c的文件,在testfile.c的这个路径下是没有testfile.txt的文件的

这时我们读一个testfile.txt文件:

这时观察结果:

告诉我们没有testfile.txt这个文件


而如果我们在testfile.c路径下创建一个testfile.txt文件:

这时再运行,就会发现不报错了:


"w"示范样例

上面示范了"r"的时候没有文件会报错,接下来试一下"w"的时候没有文件的情况:

这时依旧没有testfile.txt

代码加运行结果:

可以发现并没有报错,这时再看刚刚的文件夹:

可以发现自动创建了一个testfile.txt的文件,所以我们可以知道"w"时,如果文件不存在,会直接创建文件


上面是"w"时,文件不存在时,会自动创建出文件,那么文件存在时的情况如下:

我们原本就有testfile.txt,里面有内容为2023:

这时再运行代码:

发现文件testfile.txt里面没有内容了,可以明白"w"时,如果给的文件已经存在,则该文件会被销毁


3、文件的顺序读写

相关函数:

首先这里需要注意输入输出函数的概念:

输入是指从文件里放到程序里面,即读文件

输出指程序里的内容写到文件里面去,即写文件

fgetc

fgetc:字符输入函数

fgetc返回的是ascll码值,如果读取时遇到错误,则返回EOF

现在我们testfile.txt中有abcde

我们读文件,将他们打印出来:

当然fgetc也可以从键盘读取,stdin表示键盘


fputc

fputc:字符输出函数

需要写到文件里的字符是第一个参数,文件指针是第二个参数

运行代码之前,testfile.txt中无内容

用法如下:

这时我们的testfile.txt的内容就是abc了:

fputc也可以打印到屏幕上(stdout)


fgets

fgets:文本行输入函数

参数的意义是:将文件指针stream的内容存储到str中,num表示最大存储的个数(规定最多读num-1个)

结果为:

fgets的返回值:正确时返回str,失败时会返回空指针NULL


fputs

fputs:文本行输出函数

第一个参数传入一个字符串,第二参数传入一个文件指针

并且连续的使用fputs会加到已经存在的字符串后面

这时testfile.txt中就有以下内容:


fscanf

fscanf:格式化输入函数

fscanf与fprintf一样,都是先和scanf的用法一样,然后在第一个参数的位置添加一个文件指针 

我们的testfile.txt的内容如下:

现在想读文件:

注意我们代码中的结构体变量a,里面什么都没有,我们的内容是从testfile.txt中读取的,结果为:


fprintf

fprintf:格式化输出函数

 

看fprintf的参数后面的很复杂,其实不用管后面的参数是什么,我们平常会使用printf,只需要先像使用printf一样,然后在前面加上第一个参数:文件指针即可

下面以结构体类型示例:

testfile.txt现在是空的,运行代码后,testfile.txt内容如下:


fread

fread:二进制输入函数

 fread的四个参数与fwrite基本没有区别,具体看下面fwrite的参数含义

是从文件指针里面读取,放到ptr中去

fwrite

fwrite:二进制输出函数

 fwrite的这几个参数意义:

第一个参数ptr,表示指针指向的要写入的数据

第二个参数size,表示每个元素的大小

第三个参数count,表示最多要写入元素的数量

第四个参数是传入一个文件指针

下面是使用示例:

运行后testfile.txt的内容如下:

因为是二进制写入,而记事本是以文本的方式读取的,所以我们不认识

下面用二进制的方式读文件:

结构体变量a本身什么数据都没有,都是从文件中读取的


下面再拓展两个函数sprintf和sscanf,用以理解printf、fprintf、sprintf,scanf、fscanf,sscanf这六个函数的区别:

sprintf

sprintf是将一个格式化的数据转化成字符串

sprintf与printf的区别就是多了第一个参数,所以用法和printf一样,只需要多第一个参数str,str表示将转换的字符串存储的位置

有一个字符数组arr,初始值为0,有一个结构体变量a,现在将结构体变量a中的格式化的数据,转换为字符串存进arr,然后打印arr,发现就是我们所转化的结构体变量a的内容


sscanf 

sscanf是把一个字符串转化成格式化的数据

sscanf与scanf的区别就是多了第一个参数,即需要提取的字符串位置

通过上面的图片可以看出来,打印出来了两次数据,第一次是用sprintf,将结构体数据转化为字符串,存储到arr中打印出来的

第二次是使用sscanf将arr中的字符串提取出来,以结构体变量b格式化的形式打印(结构体变量b刚开始是没有数据的,是由arr提取出来的)


4、文件的随机读取

fseek

根据文件指针的位置和偏移量来定位文件指针

第一个参数是文件指针

第二个参数是偏移量(大于0就是向后偏移,小于0就是向前偏移)

第三个参数是起始的位置

第三个参数origin的取值有三个,分别是SEEK_CUR(文件指针当前的位置)、SEEK_END(文件末尾的位置)、SEEK_SET(文件开始的位置)

当前的testfile.txt中内容是abcdef

下面用代码演示随机读文件的用法:

testfile.txt中是abcdef,我们在fseek函数中传入的第三个参数为SEEK_SET,表示文件开始的位置,而文件最开始的位置就是指向a的偏移量为2,所以就向右偏移两位,即到了c,所以这时用fgetc得到的就是c


随机写文件的用法示例:

先在文件里写入abcd,这时文件指针当前指向d位置的下一个位置,这时使用fseek,第三个参数传入SEEK_CUR就是表示当前位置的指针,偏移量是-2,就是向左移两位,移一位指针指向d,移两位指针指向c,这时在这个位置fputc写入字符'o'

所以testfile.txt中内容就从"abcd"变为了"abod":


ftell

ftell可以返回当前指针距离起始位置的偏移量

ftell用法很简单,传入文件指针即可

这里接着上面的fseek的代码演示,最后fputc字符o后,内容为"abod",这时指针会向后移一位,即指向d,这时相对于起始位置的偏移量就是3了,打印看结果:


rewind

rewind函数是让文件指针回到文件的起始位置

rewind也是传入文件指针即可使用

我们接着上面的代码演示,刚刚ftell打印出来,偏移量相对于起始位置是3,这时我们调用rewind函数,然后再使用ftell打印偏移量,如下:


5、文本文件和二进制文件

数据文件分为文本文件二进制文件

文本文件就是我们能够看得懂的文件,二进制文件就是我们看不懂内容的意思

数据在内存中是以二进制的形式存储的

如果不转换,直接输出到外存,就是二进制文件

如果以ascll码的形式存储到外存,就是文本文件


6、文件读取结束判定

feof函数的返回值不能直接判断文件是否结束

而是应用于文件读取结束的时候,是读取失败结束还是遇到文件尾结束的


文本文件读取结束

fgetc判断返回值是否为EOF

fgets判断返回值是否为NULL


二进制文件读取结束

fread判断返回值是否小于实际要读的个数

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值