⽂件操作详解
一 文件操作的引入
1 为什么使⽤⽂件?
为了将数据进⾏持久化的保存,如果我们没有文件我们写的程序的数据其实是存储在电脑的内存中,当我们程序一退出,内存回收,数据就会丢失,等再次运⾏程序,就看不到上次程序的数据。
2 什么是⽂件?
2.1 概念:磁盘(硬盘)上的⽂件是⽂件。
⽂件名包含3部分:⽂件路径+⽂件名主⼲+⽂件后缀例如: c:\code\test.txt为了⽅便起⻅,⽂件标识常被称为⽂件名。
2.3路径的两种形式(相当路径/绝对路径)
3 文件分类(1 从⽂件功能的⻆度来分类:程序⽂件/数据⽂件 2根据数据的组织形式:为⽂本⽂件/⼆进制⽂件)
二 ⽂件的打开和关闭
1 流和标准流(其中标准流在C语⾔程序启动的时候,默认打开)
1.1 流:因为不同的外部设备的输⼊输出操作各不相同,此时为了⽅便程序员对各种设备进⾏⽅便的操作便引出了流,其实,流就是为了⽅便程序员对各种设备读取数据或者输出数据的操作,而抽象出的概念,这里我们可以把流想象成流淌着字符的河。
1.2标准流的引入
在C语言中我们如何对针对⽂件、画⾯、键盘等的数据输⼊输出操作呢?其实C程序针对⽂件、画⾯、键盘等的数据输⼊输出操作都是通过流操作的。⼀般情况下,我们要想向流⾥写数据,或者从流中读取数据,都是要打开流,然后操作。那为什么我们使用scanf和printf函数并没有直观的感觉到呢?这时候就要引入标准流。
1.3 标准流
2 ⽂件指针(⽂件类型指针)
2.1 概念:
2.2 创建⼀个FILE*的指针变量
int main()
{
FILE* pf;//⽂件指针变量return 0
}
3 ⽂件的打开和关闭
3.2使用文件的固定步骤
fopen 函数原型:
fclose函数原型:
3.3 文件的打开模式
其中常用的只要几个。
1
三 ⽂件的顺序读写
下面我们来介绍几个顺序读写函数,我们可以利用这几个顺序读写函数在结和文件的打开模式对文件进行操作。
顺序读写函数:
1 fgect函数
1.1 这是一个字符输入函数个,适用于所有输入流。
示例:
这里我们运用"r"只读的方式打开文件,这里我们是进行字符的读取,所以我们应在相应文件中放上内容 再看相应文件中的内容:
再看运行结果:
注意在读取字符时它会从第一个字符的位置开始读取,当每次读取完成后,光标会往后移动一位,利用这一特性,再利用循环进行读取,这样我们就可以达到像读取字符串一样,当我们想读取的个数比读取文件中的个数多会发生什么呢?这时候多余的会打印出错误信息(这里我就不举例了,感兴趣的可以自己试一试。特别注意fgetc在遇到空格时会选择跳过
1.2 这个函数适用于使用输入流,那意味着对于标准流也有用。
这里我们先输入一个字符便可以打印出相应的字符。
2 fputc函数
2.1 这是一个字符输出函数,适用于所有输出流。
示例:
现在我们打开文件观察其运行结果:
这里我们发现文件中已经有了相应的字符,但是我们·发现文件中的字符全部都在一行这是为什么呢?其实fputc函数也能识别”\0"只要其识别到”\0"结束标识符时才会换行。那这里有一个问题很值得我们思考,上面的fgect函数适用于使用输入流,是一个字符输入函数,而fputc函数这个函数适用于使用输出流,是一个字符输出函数。那么这两个函数是否呢结和使用呢?
将fgect函数和fputc函数结和使用:
这里我们发现将fgect函数和fputc函数结和使用结果是不行的,因为"w"模式是写入模式,会清空文件内容,在写入之后,在进行读取操作不会得到任何内容。
2.2 这个函数适用于使用输出流,那意味着对于标准流也有用。
3 fgets函数
这是一个文本行输入函数,适用于所有输入流。(文本行即能对一行操作)
这个函数有三个参数分别是存放读取字符串的地址、读取的字符个数、文件指针。
示例:
我们看一看文件中都内容:
4 fputs函数
这是一个文本行输出函数,适用于所有输出流。(文本行即能对一行操作)
这个函数有两个参数分别是:字符串地址和文件指针
示例1:
结果:
示例2:
5 fscanf函数
这是一个格式化输⼊函数函数,适用于所有输入流(格式化即特定的格式可以包含多个类型)。
我们发现这个函数的原型有些神奇,他的参数里面居然有个省略号!也就是说,它支持传入的参数个数是无限制的!要想熟练使用fscanf函数就得仿造scanf函数它们只相差一个参数fscanf函数比scanf函数多了一个文件指针。
示例:
文件内容:
运行结果:
6 fprintf函数
这是一个格式化输出函数,适用于所有输出流(格式化即特定的格式可以包含多个类型)。
它的使用可以类比于printf函数比printf函数多了一个参数( 文件指针)
示例:
7 fread函数
这是一个⼆进制输⼊函数,适用于文件输入流。
这个函数传入的参数就相对来说复杂了一些:分别是存放字符串的地址、数据的字节大小、数据的数量、文件指针。
示例:
8 fwrite函数
这是一个⼆进制输出函数,适用于文件输出流。
示例:
四 ⽂件的随机读写
1 fseek函数
int fseek ( FILE * stream, long int offset, int origin );
第一个参数就是文件指针,没什么好说的,通过上前面的学习我们发现这种文件操作函数基本都要输入文件指针。
第二个参数是偏移量参数,可以为正数,也可以为负数。
第三个参数是起始位置
- 文件头
SEEK_SET
0- 当前位置
SEEK_CUR
1文件尾
SEEK_END
2
2 ftell函数
这个函数可以返回文件指针相对于起始位置的偏移量
long int ftell ( FILE * stream );
我们直接传文件指针就行,他会返回光标位置相较于文本最开始的偏移量
3 rewind函数
这个函数可以让文件指针的位置回到文件的起始位置。
void rewind ( FILE * stream );
示例:
五 ⽂件读取结束的判定
1⽂本⽂件读取是否结束/⼆进制⽂件的读取结束判断
我们都知道,EOF是文件结束的标志,那么feof呢?
判断返回值是否为 EOF ( fgetc ),或者 NULL ( fgets )•fgetc 判断是否为 EOF .•fgets 判断返回值是否为 NULL .
判断返回值是否⼩于实际要读的个数。•fread判断返回值是否⼩于实际要读的个数。
2 ⽂本⽂件的例⼦:
3 ⼆进制⽂件的例⼦:
运行结果:
六 ⽂件缓冲区
缓冲⽂件系统是指系统⾃动地在内存中为程序中每⼀个正在使⽤的⽂件开辟⼀块“⽂件缓冲区”。在C语言文件操作时,其实我们读取文件内容和输入内容到文件时,并不是直接对其进行操作的,而是通过文件缓冲区操作。那为什么会有⽂件缓冲区呢?其目的是为了提高编程效率假如没有⽂件缓冲区,这是我们要对一个字符串操作时如果没有⽂件缓冲区,我们就要不断对每个字符重复的进行操作,如果有了⽂件缓冲区我们把像输入的字符一个一个先放入缓冲区,等到积攒到了一定的数量,超过缓冲区范围,再把缓冲区的字符一次性放到硬盘中,这样就能减少系统的运行压力。记住缓冲区的⼤⼩根据C编译系统决定的。
本篇文章就到此结束,欢迎大家订阅我的专栏,欢迎大家指正,希望有所能帮到读者更好了解⽂件操作相关知识 ,觉得有帮助的还请三联支持一下~后续会不断更新C/C++相关知识,我们下期再见。