个人主页
今天我们来讲一下有关文件的相关操作,希望看完这篇文章对你有所帮助,大力感谢你对博主的支持!
文章目录
- ⭐一、为什么使用文件
- 🎉二、什么是文件
- 2.1 程序文件
- 2.2 数据文件
- 2.3 文件名
- 🎡三、二进制文件和文本文件
- 🚀四、文件的打开和关闭
- 4.1 流和标准流
- 4.2 文件指针
- 4.3 文件的打开和关闭
- 🏝️五、文件的顺序读写
- 5.1 fgetc (字符输入函数)
- 5.2 fputc (字符输出函数)
- 5.3 fgets (文本行输入函数)
- 5.4 fputs (文本行输出函数)
- 5.5 fscanf (格式化输入函数)
- 5.6 fprintf (格式化输出函数)
- 5.7 fread (二进制输入)
- 5.8 fwrite (二进制输出)
- 🎄六、文件的随机读写
- 6.1 fseek
- 6.2 ftell
- 6.3 rewind
- 🚆七、文件读取结束的判定
- 🚘八、文件缓冲区
⭐一、为什么使用文件
在日常中,我们写的程序的数据是存储在电脑的内存中,如果程序退出,内存就会被回收,数据就丢失了。我们再次运行程序时就看不到上次程序的数据。因此像要将数据进行持久化的保存,我们就需要使用文件。
🎉二、什么是文件
磁盘(硬盘)上的文件是文件。
但是在设计程序中,我们一般把文件分为两种:一是程序文件,另一个是数据文件。(从文件功能的角度进行分类)
2.1 程序文件
程序文件包括源程序文件(后缀为.c),目标文件(windows环境后缀为.obj),可执行程序(windows
环境后缀为.exe)。
2.2 数据文件
程序运行时读写的数据,比如程序运行需要从中读取数据的文件,或者输出内容的文件。
2.3 文件名
文件名包含3部分:文件路径+文件名主干+文件后缀
例如:c:\code\test.txt
注意:文件标识常被称为文件名。
🎡三、二进制文件和文本文件
数据在内存中以二进制的形式存储,如果不加转换的输出到外存的文件中,就是二进制文件。
如果要求在外存上以ASCII码的形式存储,则需要在存储前转换。以ASCII字符的形式存储的文件就是文本文件。
我们以二进制存储的方式举例:
int main()
{int a = 10000;FILE * pf = fopen("test.txt", "wb");fwrite(&a, 4, 1, pf);//⼆进制的形式写到⽂件中 fclose(pf);pf = NULL;return 0;
}
由于我们是以二进制的存储方式,因此打开文件的方式也要用二进制的打开方式
编译器是以小端存储且以16进制的方式进行打印
🚀四、文件的打开和关闭
4.1 流和标准流
流
• 由于我们程序的数据需要输出到各种外部设备,也需要从外部设备获取数据,而不同的外部设备的输入和输出操作各不相同,因此为了程序员方便操作,抽象出了流的概念,我们可以把流想象成流淌着字符的河。
• C程序针对文件、画面和键盘等的数据输入和输出操作都是通过流来进行操作的。
• 一般情况下,我们要想向从流里写数据,或者从流中读取数据,都是需要打开流,然后操作。
标准流
为什么我们从键盘中输入数据,向屏幕上输出数据时,并没有打开流呢?那是因为C语言程序在启动的时候,默认打开了3个流:
• stdin - 标准输入流,在大多数的环境中从键盘输入,scanf函数就是从标准输入流中读取数据。
• stdout - 标准输出流,大多数的环境中输出至显示器界面时,printf函数就是将信息输出到标准输出流中。
• stderr - 标准错误流,大多数环境中输出到显示器界面。
4.2 文件指针
缓冲文件系统中,关键的概念是 “文件类型指针”,简称“文件指针”
每个被使用的文件都在内存中开辟了⼀个相应的文件信息区,用来存放文件的相关信息(如文件的名字,文件状态以及文件当前的位置等)。这些信息是保存在⼀个结构体变量中的。该结构体类型是由系统声明的,取名FILE
4.3 文件的打开和关闭
文件在读写之前应该先打开文件,在使用结束之后应该关闭文件。
ANSIC规定使用 fopen 函数来打开文件, fclose 函数来关闭文件。
//打开⽂件
FILE * fopen ( const char * filename, const char * mode );//关闭⽂件 int fclose ( FILE * stream );
文件的打开模式有很多种,例如:“r” 表示输入数据,打开一个已经存在的文本文件;“w” 表示输出数据,打开一个文本文件,若该文件不存在则建立一个新文件;“a” 表示向文本文件末尾添加数据等等,这里就不一一赘述了。
下面我们就以写的方式举个例子:
🏝️五、文件的顺序读写
5.1 fgetc (字符输入函数)
函数形式:int fgetc ( FILE * stream );
该函数成功读入数据时会返回读取字符的ASCII值,否则则会返回EOF。
例如:假如.c路径下有一文件名叫test.txt,该文件中有字符串”abcdef"
5.2 fputc (字符输出函数)
函数形式:int fputc ( int character, FILE * stream );
该函数返回文件指针当前指向的字符,文件指针向后移动一位
如果文件指针位于文件末尾,那么就返回EOF,并为流设置feof的文件结束显示器
如果文件读取错误,同样返回EOF,为流设置为错误显示器ferror
例如:向一个文件写入26个小写英文字符
5.3 fgets (文本行输入函数)
函数形式:char * fgets ( char * str, int num, FILE * stream );
从流中读取字符,并以字符串的形式存储到str中。 直到读够(num - 1)个字符,或到达换行符,或读到文件末尾时才停止
如果读取成功,则返回str的头指针,若读取失败,则为流设置错误显示器,并返回空指针。
5.4 fputs (文本行输出函数)
函数形式:int fputs ( const char * str, FILE * stream );
将str中的字符串输出到流中,结束符‘\0’不会被写入
5.5 fscanf (格式化输入函数)
函数形式:int fscanf ( FILE * stream, const char * format, ... );
以格式化的形式从流中读取数据
例如:从文件中读取字符串 “abcd”
5.6 fprintf (格式化输出函数)
函数形式:int fprintf ( FILE * stream, const char * format, ... );
将格式化的数据输出到指定流。
5.7 fread (二进制输入)
函数形式:size_t fread ( void * ptr, size_t size, size_t count, FILE * stream );
以二进制的形式从流中读取count个元素,每个元素的大小为size字节,并将它们存储在 ptr 指定的内存块中。
返回成功读取的元素总数。
5.8 fwrite (二进制输出)
函数形式:size_t fwrite ( const void * ptr, size_t size, size_t count, FILE * stream );
以二进制的形式将ptr存储的数据写入流中,一共写入count个元素,每个元素的大小为size字节
返回成功写入的元素总数。
int main()
{int a = 10000;FILE * pf = fopen("test.txt", "wb");fwrite(&a, 4, 1, pf);//⼆进制的形式写到⽂件中 fclose(pf);pf = NULL;return 0;
}
🎄六、文件的随机读写
6.1 fseek
函数形式:int fseek ( FILE * stream, long int offset, int origin );
offset为偏移量
origin为起始位置,有三种取值:
SEEK_SET:文件头
SEEK_CUR:文件指针的当前位置
SEEK_END:文件尾
如果成功,则返回0,否则返回非零值
例如:在data.txt文件中有字符串"abcdefghi",从a的位置偏移四位就得到f
6.2 ftell
函数形式:long int ftell ( FILE * stream );
返回文件指针相对于起始位置的偏移量
假设.c路径上的data.txt文件中存储字符串“abcdefghijk”
6.3 rewind
函数形式:void rewind ( FILE * stream );
让文件指针的位置回到文件起始位置
🚆七、文件读取结束的判定
牢记:在文件读取过程中,不能用feof函数的返回值直接来判断文件的是否结束。
feof 的作用是:当文件读取结束的时候,判断是读取结束的原因是否是遇到文件尾结束。
• 文本文件读取是否结束,判断返回值是否为 EOF
• fgetc 判断是否为 EOF
• fgets 判断返回值是否为 NULL
二进制文件的读取结束判断: 判断返回值是否小于实际要读的个数
🚘八、文件缓冲区
ANSIC标准采用“缓冲文件系统”来处理的数据文件的,所谓缓冲文件系统,是指系统能自动地在内存中为程序中每⼀个正在使用的文件开辟⼀块“文件缓冲区”。从内存向磁盘输出数据会先送到内存中的缓冲区,装满缓冲区后才⼀起送到磁盘上。
缓冲区的大小根据C编译系统决定的。
今天的分享到这里就结束了,如果感到对你有所帮助,希望给博主一键三连,你的支持就是对博主最大的鼓励,我们下期再见!