这一章,让我们一起来学习一下关于C语言文件操作的知识吧!
一.使用文件的原因
使用文件是为了将数据进行持久化的保存。如果不使用文件,我们所写的数据会存储到内存中,当程序运行结束时,内存回收,数据就会丢失,当我们下次再打开运行这个程序时,上一次的数据就无法得知。因此为了持久性的保存数据,我们使用文件。
二.什么是文件
磁盘(硬盘)上的文件是文件,在程序设计时,我们常常将文件分为程序文件和数据文件(根据文件的作用来分类)。
1.程序文件
程序文件包括源程序文件(.c),目标程序文件(.o),和可执行程序文件(.exe)。
2.数据文件
文件不一定是程序,还有可能是我们输入的数据。
数据文件分为文本文件和二进制文件
3.文件名
文件名:文件保存路径+文件名主干+文件后缀
eg:c:\code\test.txt
三.二进制文件与文本文件
数据文件根据数据的不同组织形式分为二进制文件和文本文件。
数据以二进制的形式存储,不加以转换直接输入到文件中形成二进制文件。
数据以ascll码的形式存储,不加以处理直接输入到文件中形成文本文件。
我们不妨举个例子来看一下数据在这两种文件中具体是怎么存放的。例如:10000
四.文件的打开与关闭
1.流和标准流
数据是通过各种外部设备输入与输出,不同外部设备的输入与输出不同,为了方便程序员的操作,我们抽象出了“流”的概念,把它想象成流淌着字符的“河”,C语言针对文件、画面、键盘的操作都可以通过流来实现。当我们需要向流里写入数据,我们就打开流,写完后关闭流。
标准流,是针对于键盘与屏幕的输入输出而设定的流。C语言中默认打开了三种标准流:
·stdin标准输入流 从键盘输入,scanf函数就是从标准输入流中读取数据。
·stdout标准输出流 printf函数就是将信息输出到标准输出流中,显示在屏幕上。
·stderr标准错误流 大多数环境中显示到显示器界面。
这三种标准流都是通过printf和scanf进行输入输出的。
2.文件指针
我们上面所讲的三种标准流的类型都是FILE*,叫做文件指针。C程序就是通过文件指针来操纵各种流的。那么文件指针具体是什么呢?实际上,文件在创建的时候,会创建一个结构体来存储此文件的相关信息,该结构体被重命名为FILE而文件指针则是指向这个结构体。如:
FILE*pf,pf为文件指针变量,通过文件指针变量可以直接找到结构体,间接找到此文件。
我们可以通过下图来理解:
3.文件打开与关闭
文件在读写之前需要打开,读写完成之后需要关闭。
文件的打开与关闭也是使用了相关函数来完成操作。
那么文件是如何打开的呢?C语言规定函数fopen来打开文件,用fclose来关闭文件。
mode代表打开的方式,文件打开有多种mode:
具体的实现我们可以通过下面的代码来一窥究竟:
五.文件的顺序读写
1.顺序读写函数
当我们打开文件之后,就需要对文件进行读写。
那么接下来我们来了解几个文件的顺序读写函数。
所有输入流指的是其他输入流(如文件输入流)和标准输入流,所有输出流代表其他输出流(如文件输出流)和标准输出流。
那么接下来我们写几个代码来看一下这几个重要顺序读写函数具体的功能:
·fgetc: int fgetc(FILE*stream)
如果成功读取,返回ascll码值;读取失败,返回EOF(-1),所以返回类型我们写为int。fgetc一次读一个字符,读一个光标自动向后移动一个。
·fputc: int fputc(int character,FILE*stream)
一次写一个字符,每次写完光标向后移动一个。
·fputs: int fputs(const char*str,FILE*stream)
把字符串输出到文件中。
·fgets: char*fgets(char*str,int max_num,FILE*stream)
从文件从得到字符串,存放在str以str为首元素地址的字符数组中。其中max_num为要读取的字符串大小,这其中包含一个字符\0。
2.对比
接下来我们来对比几组函数。
·printf/fprintfsprintf
printf是从输出到屏幕。
fprintf是以格式化的形式输出到标准流或其他流(如文件)
sprintf是把格式化的数据转化成字符串。
·scanf/fscanf/sscanf
scanf是输入到键盘。
fscanf是以格式化的形式输入到标准流或其他流(如文件)
sscanf是在字符串中读取格式化的数据
六.文件的随机读写
下面这三个函数与顺序读写函数一块使用可以做到文件的随机读写。
1.fseek
这个函数根据文件指针的位置和偏移量来定位文件指针(光标)。这个函数的原型是:
int fseek(FILE*stream,long int offset,int origin) 第二个参数代表偏移量,第三个参数代表起始位置。其中,起始位置有三种可能:
·文件起始位置 SEEK_SET
·文件指针当前位置SEEK_CUR
·文件末尾SEEK_END
我们来举一个格式例子了解一下这个函数是如何使用的:
fseek(pf,4,SEEK_SET);
2.ftell
这个函数可以告诉我们相对于起始位置光标的偏移量。他的原型是:
int ftell(FILE*stream)
3.rewind
这个函数的作用是让文件指针回到文件起始位置。它是这样使用的:
rewind(FILE*stream)
七.文件读取结束的判定
我们如何判断文件是否读取结束呢?
·文本文件读取结束的判断:
①利用fgetc判断返回值是否为EOF
②利用fgets判断返回值是否为NULL
·二进制文件读取结束的判断:
判断读取结束,看实际读取个数是否小于要求读取个数。
那么判断完是否读取结束后,如果我们还想知道读取结束的原因是什么,我们应该如何做呢?
我们会使用两个函数:
feof:判断读取结束的原因是否为遇到了文件结尾,如果是,则返回非0元素,如果不是,则返回0。
ferror:判断读取结束的原因是否为发生错误。如果是,则返回非0元素,如果不是,则返回0。
八.文件缓冲区
ANSIC 标准采⽤“缓冲⽂件系统” 处理的数据⽂件的,所谓缓冲⽂件系统是指系统⾃动地在内存中为程序中每⼀个正在使⽤的⽂件开辟⼀块“⽂件缓冲区”。从内存向磁盘输出数据会先送到内存中的缓冲区,装满缓冲区后才⼀起送到磁盘上。
如果从磁盘向计算机读⼊数据,则从磁盘⽂件中读取数据输⼊到内存缓冲区(充满缓冲区),然后再从缓冲区逐个地将数据送到程序数据区(程序变量等)。缓冲区的⼤⼩根据C编译系统决定的。
好了,关于C语言文件操作我们就讲到这里,希望屏幕前的你能够有所收获,感谢大家的收看,欢迎批评指正!我们下期再会!