目录
我们存储的文件指是磁盘(硬盘)上的文件,放在硬盘上可以将数据进行持久化的保存;
但是在程序设计时,我们通常谈到两种文件:程序文件和数据文件;
文件
程序文件
1)源程序文件:后缀是.c的文件;
2)目标文件:windows环境后缀是.obj(在编译和链接中会专门讲解);
3)可执行文件:windows环境后是.exe;
数据文件
数据文件的内容不一定是程序,而是程序运行时读写的数据;比如,程序运行需要从中读取的数据文件,或输出内容的文件;
文件名
一个为了将要有唯一的文件标识,便于查找文件;
文件名包含三个部分:1)文件路径;2)文件主干;3)文件后缀;
数据文件的分类
根据数据的组织形式,数据文件被分为二进制文件和文本文件;
1)二进制文件:数据在内存中++以二进制的形式存储++,如果不加转换的输出到外存的文件中,就是二进制文件;
2)文本文件:如果要求在外存文件上++以ASCII码值的形式存储++,则需要在存储前进行转化,以ASCII码值的形式存储的文件叫做文本文件;
注意:储存的时候,字符一律以ASCII码值的形式存储,数值型数据可以以ASCII码值的形式存储,也可以以二进制的形式存储;
比如:10000,如果以二进制输出到磁盘上,则在磁盘上只占4个字节;如果以ASCII码值进行输出,每个字符一个字节,则需要5个字节;
文件的打开和关闭
如何用C语言打开一个文件;
流
我们程序的数据需要输出到 各种外部设备 ,也需要从外部设备获取数据,不同的外部设备的输⼊输出操作各不相同,为了⽅便程序员对各种设备进⾏⽅便的操作,我们抽象出了流的概念;
C程序针对⽂件、画⾯、键盘等的数据输⼊输出操作都是通过流操作的。
专门用来将文件和不同的外部设备建立关系;
文件的打开就是:1)打开文件(打开流);2)读写文件;3)关闭文件(关闭流)
标准流
我们在键盘上输入数据,向屏幕输出数据的时候,好像并没有看见打开了文件(流);因为在C语言程序启动时会默认打开3个标准流;
1)stdin
标准输入流,在大多数环境从键盘输入,scanf函数就是从标准输入流中提取数据;
2)stdout
标准输出流,在大多数环境中输出至显示器界面,printf函数就是将信息输出到标准输出流中;
3)stderr
标准错误流,大多数环境中输出(程序错误)到显示器界面;
stdin,stdout,stderr三个流的类型:FILE*,是一个文件指针;
文件指针
文件指针是用来管理流的;
每一个被使用的文件(在硬盘上)都在内存中开辟了一个相应的文件信息区(在内存中),用来存储文件的相关信息,这些信息被保存在一个结构体变量中,该结构体的类型是由系统声明的,取名为FILE;
一般用FILE*的指针来维护FILE结构变量;
定义一个FILE*的指针相当于找到了文件的地址;
文件的打开和关闭
1)打开文件;2)读取文件;3)关闭文件;
在ANSI C标准中,规定用fopen来打开文件;
filename是指的是打开的文件名称,mode是文件打开的形式;
关闭文件用fclose;
关闭文件后,要把文件指针置为空指针;
后面会讲解对文件进行写操作;
注意:路径包含绝对路径和相对路径两种,这里就不再讲解了;
对文件内容操作的函数
1)fgetc,fputc
fgetc函数,形式:int fgetc(FILE* stream);从流中读取一个字符,当读取成功时,返回这个字符的ASCII码值,当读取错误的时候,返回EOF;
fputc函数,形式:int fputc(int character,FILE* stream);将字符输出到流中;
2)fputs
fputs是用来将一串字符输出到文件中的;输出成功返回一个非负数,输出失败返回EOF;
3)fgets
fgets是拷贝函数;将流中的数据,拷贝最多num个倒str地址处;返回值是拷贝完成的起始地址;
可以看到记事本中的字符确实拷贝到了arr数组中,但是num是10,为什么只拷贝了9个?因为在使用fgets的时候会默认最后一个补'\0'上去,所以减少了一位字符的拷贝;若拷贝内容中含有换行符,则拷贝到换行符后自动停止拷贝;
4)fprintf
可以看到,printf和fprintf 的区别在于fprintf多了一个FILE* stream所以fprintf是把信息写在文件上的,而不是输出到屏幕上;
5)fscanf
与fprintf类似,fscanf不是从标准输入流中读取,而是从指定的stream流中读取;
6)sprintf
sprintf是将格式化的数据写到字符串中,即将格式化的数据转换成字符串;
将name字符串和c整形数据转化为字符串放在arr中;
7)sscanf
sscanf和sprintf的作用相反,其是将字符串转化成格式化数据;
sscanf是从arr地址开始读的,不是从键盘上读取;
7)fread,fwrite
fread和fwrite可以进行二进制的读写;
fread是将ptr地址处count个大小为size的元素以二进制的方式写入stream流中;
要用二进制的方式打开才能看到里面的数据,记事本不是以二进制的方式打开;
fread是从流中以二进制的方式读取num个size大小的数据放在str地址处,与fwrite相反,此处不再赘述了;
文件的随机读写
在进行对文件的操作的时候,文件中光标在时刻移动;在对文件进行读写的时候,我们又是不希望它从起始位置开始,此时我们就需要改变光标的起始位置。
1)fseek
fseek函数是专门用来改变文件光标的起始位置的;
从origin开始偏移量为offset**(可以是负数)**;
origin有三种,文件起始位置,当前位置,末尾;
2)ftell,remind
ftell是用来告诉你此时文件指针(光标)位置的,其返回文件相对于起始位置的偏移量;
rewind是重置光标位置的,让文件指针(光标)位置回到起始位置;
文件读取结束的判定
判断方法:
1)文本文件读取是否结束,判断返回值是否是EOF(fgetc),或者NULL(fgets);
2)二进制文件的读取结束判断,判断fread的返回值是否小于要读取的个数;
注意:feof是用来判断文件读取结束的原因是否是遇到了文件末尾,而不是判断文件是否读取结束;当读取到文件末尾,则返回一个非0值;