1.为什么使用文件
程序运行结束后会释放内存,不会保留其中产生的数据,而文件可以把数据保存下来.
2.文件的类型
1.从功能上分类:程序文件和数据文件.程序文件是可以运行的,比如exe文件;数据文件储存程序运行是需要的数据.
2.从储存方式上分类:二进制文件和文本文件.不同储存方式的文件读取时需要不同类型的读取器.
需要注意的是文本文件不是字面意思上储存的是文本内容,而是将其ASCLL储存,比如要存123这个数字:
文本文件: 49 50 51(实际上就是字符'1' '2' '3'的ASCLL码) 二进制文件: 1111011
3.文件名(文件标识)的组成
4.文件的打开和关闭.
1.流
从键盘,网络,c盘等储存设备中读取数据的读取方式方式各不相同,同样的,输出数据的方式也有许多(比如输出到屏幕,写在文件中);为了方便,c程序抽象出了流的概念,不去探讨流的底层逻辑,可以把流想象成河流,输入时将数据倒入河流,输出时从河流取出.
2.标准流
c程序启动时,默认打开三个流.
stdin-标准输入流(大多数环境是从键盘输入)
stdout-标准输出流(大多数环境是输出到显示器)
stderr-标准错误流(大多数环境是输出到显示器)
这三个流的类型是FILE* (文件指针),指向三个功能不同的文件.
5.文件指针
一但你试图在程序中使用某个文件,都会在内存中开辟一个文件信息区,其实是在内存上创建了一个名叫FILE类型的结构体变量,这个结构体储存了文件相关信息.当然,FILE这一结构体类型是系统提前创建的.
而文件指针就是指向这一结构体变量的指针.
6.文件打开和关闭
文件使用前要打开,使用后需要关闭,分别使用fopen("文件名","打开方式")和fclose("文件名").fopen使用后会返回一个指向这个文件的指针,当然如果打开失败会返回NULL.
打开方式如下:
要注意的是,w,w+wb+每打开一个文件会先清除所有内容.
使用例子如下:
注意:如果不使用绝对路径(完整的建立路径,如:c:\yyy\xxx\xx.txt)而是直接用文件名(xx.txt),每次建立新文件夹的时候都会在默认路径,如果想要在默认路径前一个目录(如:xxx)中建立,只需要把("test.txt","w+")改为("./../test.txt","w+"),前两个就是("./../../test.txt","w+").
7.在程序中顺序读写文件
操作文件需要用到顺序读写函数如下:
所谓所有输出流可以浅薄的理解为你可以在显示器上输出(输入),也可以在文件中输出,当然,只有文件就是只能输出(输入)到文件中.
接下来介绍一下这些函数的使用:
返回这个字母的ASCLL码,失败返回EOF
返回这个字母的ASCLL码
返回string位置,失败返回NULL. n表示最多读取n-1个字符(因为给'\0'留了位置)
返回一个非负的值
与scanf参数唯一不一样的地方是多了stream这个参数.
与printf参数唯一不一样的地方是多了stream这个参数.
ptr是储存数据的地址,size是数据大小,count是数据数量.当然,都是二进制形式读入.返回读到元素个数
buffer是要写的数据地址,size是数据大小,count是数据数量.当然,都是二进制形式写入.返回元素个数
将s指向的字符串格式化的读取,
把格式化的数据转换为字符串
举个使用的例子:
文件流输出:
标准流输出(暂时理解为显示器):
这是另一个例子,拷贝文件:
这也是例子:
光标也叫文件指针.
所谓顺序读写就是输入(输出)时,光标会随着输入(输出)的数据移动,读写完一个数据,光标就移动向下一个数据,按顺序全部读写(然而,文件一旦关闭,重开时光标会移动到起始位).
所谓逆序就是我在合理范围内可以让光标任意移动,想要读写哪儿就移动到哪儿去.
8.在程序中逆序读写文件
实现逆序读写需要依靠函数:
1.
stream是文件名,origin是你规定偏移量为0的地方{有三种选择:SEEK_SET(文件开头),SEEK_CUR(目前光标的位置),SEEK_END(文件末尾)},offset是你要移动到偏移量为offset的位置.
打个比方:fseek(stream,-8,SEEK_CUR)就是把光标从当前位置向前移动8位.
fseek(stream,2,SEEK_SET)就是把光标移动到起始位置向后2位的地方
2.
返回目前光标位置相对于起始位置的偏移量.
3.
将光标移动到起始位置.
9.文件读取结束的判定
1.
只能判断是否因为遇到文件结尾而退出
只能判断是否因为遇到错误而退出
这两个一般一起使用,因为不是只有这两种退出原因.
2.fread返回实际读取到的个数,如果小于要读取的个数就是异常结束
3.当然,还可以利用fgets和fgetc的返回值判断,这里不再赘述.
小知识:
顺序表优点:1.下标随机访问。2.cpu高速缓存命中率高。
顺序表缺点:1.插入删除效率低下。2.扩容导致效率损失,也可能空间浪费。
链表(带头双向为主)优点:1.插入删除效率高。2.按需申请空间,不浪费。
链表(带头双向为主)缺点:1.不支持下标访问。2.cpu高速缓存命中率低。