目录
一.为什么要使用文件
如果没有文件,我们写的程序的数据是存储在电脑的内存中,如果程序退出,内存回收,数据就丢失了,等再次运行程序,是看不到上次程序的数据的,如果要将数据进行持久化的保存,我们可以使用文件。
二.文件的打开与关闭
1.流和标准流
我们程序的数据需要输出到各种外部设备,也需要从外部设备获取数据,不同的外部设备的输入输出操作各不相同,为了方便程序员对各种设备进行方便的操作,我们抽象出了流的概念,我们可以把流想象成流淌着字符的河。
C程序针对⽂件、画面、键盘等的数据输⼊输出操作都是通过流操作的。
⼀般情况下,我们要想向流⾥写数据,或者从流中读取数据,都是要打开流,然后操作。
2.标准流
那为什么我们从键盘输⼊数据,向屏幕上输出数据,并没有打开流呢?
那是因为C语言程序在启动的时候,默认打开了3个流:
stdin标准输⼊流,在⼤多数的环境中从键盘输⼊,scanf函数就是从标准输⼊流中读取数据。
stdout标准输出流,⼤多数的环境中输出至显示器界面,printf函数就是将信息输出到标准输出
流中。
stderr标准错误流,⼤多数环境中输出到显示器界⾯面。
这是默认打开了这三个流,我们使用scanf、printf等函数就可以直接进行输⼊输出操作的。
stdin、stdout、stderr三个流的类型是: FILE * ,通常称为文件指针。
C语言中,就是通过 FILE* 的文件指针来维护流的各种操作的。
3.fopen与fclose
C语言中提供了函数fopen与fclose进行文件的打开与关闭,我们在对文件进行读写时,需要先打开文件,不需要使用时再关闭
fopen用来打开文件,fclsoe用于关闭文件
fopen函数包含两个参数,第一个参数需要用 “ 文件路径和文件名“ 的形式来输入,对于第二个参数,只能输入访问模式,如”r”就是read,读文件,只能读取文件的内容,“w”write,写文件,只能向文件中写入内容,如果成功打开文件,会返回一个文件指针,如果失败会返回NULL
(我们通常会判断它的返回值是否为NULL,但是在文章中,我们省略了这个判断以及与之类似的异常判断)
对于第一个参数:如果文件在当前工作目录,那么只需要输入文件名即可(在输入路径时,需要使用转义字符\\来表示\)
fclose用于关闭文件,只有一个参数,文件指针
fopen与fclose一般是组合使用,示例:
三.文件的顺序读写
1.fgets
读取成功,返回字符的ASCII码值,读取失败,返回EOF,读取后光标后移
这里,我们以读的形式打开文件,并且使用fgetc函数读取文件第一个字符,使用ret接收返回值,a的ASCII码值是97(在文件关闭后,我们为了防止p成为野指针,我们将其赋值为NULL)
2.fputc
fputc与fgetc的使用方式差不多,但是要注意使用fputc时需要以写的方式打开文件
两个参数,第一个是想要写入字符的ASCII码值或者是字符本身,第二个是流
如果写入成功,返回字符的ASCII码值,失败返回EOF
写入后,光标后移
3.fgets
三个参数,第一个是读取到的内容存储到的地址,一般为一个字符数组,第二个是读取的个数,当读取num-1个字符时停止,第三个参数就是流
读取 (num-1) 个字符,或者到达换行符或文件末尾时,函数停止
换行符\n会使函数停止,并且将换行符赋值到str中,fgets会在读取结束后自动加上\0
这里,我们读取4个字符后停止,打印出arr的内容abcd(arr的第五个元素为\0)
4.fputs
从str中复制字符向流中写入,写入成功后返回一个非负值,遇到\0停止
这里,我们成功将arr的内容abcd赋值到文件中,并且打印出返回值是0
5.fscanf
此函数与scanf类似,只是由从键盘上读取内容变为从流中读取
项目数就是假设你%d %s %f如果都写入成功,那么项目数就是3
这里,我们从文件中读取格式化的内容放到a b f中,(忽略我给a b f 的初始化),并且我们打印出来了函数的返回值(第一个打印的内容“3”),因为我们三个项目都成功读取,所以返回值就是3
6.fprintf
这里,我们成功向文件中写入格式化的数据,并且打印出它的返回值13,因为我们成功写入了13个字符
7.fwrite
fwritre是向文件中写二进制信息的函数,它有4个参数,写入信息的地址,元素的大小,元素的个数,流
他的返回值是成功写入的个数(此函数与其他写入函数使用方式类似,不过多演示,需要注意的是,它写入的是2进制的信息)
8.fread
fread是从文件中读取2进制信息的函数,只适用于2进制输出的文件输出流
它包含4个参数,分别为一个写入读取内容的地址(通常为一个数组),读取元素的大小,读取元素的个数,最后一个是流,也就是FILE*类型的指针
!!!!它的返回值是成功读取元素的个数,如果返回值小于你的第三个参数,那么说明这是最后一次读取,后面没有内容了。
四.文件的随机读写
有时候我们不想按着顺序一个个读取或写入文件中的内容,那么我们可以通过改变光标的位置来达到目的
1.fseek
三个参数,流,偏移量,起始位置
注意,第三个参数只有三个选项,
SEEK_SET,文件起始位置 SEEK_CUR,文件指针的位置 SEEK_ENG 文件末尾的位置
此函数能够在读取文件内容时改变光标的位置,达到随机读写的效果
这里,我们先读取前两个字符并且打印,然后调整光标的位置,使其后移两位,到达e的位置,然后读取一个字符e
2.ftell
能够返回一个long int类型的整数,告诉你现在光标距离文件起始位置的偏移量,参数只有一个,就是流
3.fewind
让文件指针回到文件起始的位置,参数只有一个FILE*类型的流
五.文件读取结束的判定
被错误使用的 feof
牢记:在文件读取过程中,不能用feof函数的返回值直接来判断文件的是否结束。
feof 的作用是:当⽂件读取结束的时候,判断是读取结束的原因是否是:遇到文件尾结束。
文本文件读取是否结束,判断返回值是否为 EOF ( fgetc ),或者 NULL ( fgets )
例如:
• fgetc 判断是否为 EOF .
• fgets 判断返回值是否为 NULL .
• fread判断返回值是否小于实际要读的个数。