前言
这次介绍的是文件操作,名字都叫文件操作,是需要大家去多多尝试和操作的。大家跟上我的节奏冲冲!!
目录
1.为什么要使用文件呢?
如果没有文件,我们写的程序的数据是存储在电脑的内存中,如果程序退出,内存回收,数据就不见了!!。下次运行就看不到了数据,要持续化的保存数据,我们就要用到文件。
2.什么是文件!
在程序设计中我们一般就考虑两种:程序文件,数据文件(从文件功能角度来进行分类为)。
2.1程序文件
程序文件包括:源程序文件(后缀为.c的),目标文件(在windows环境下后缀为.obj),可执行文件(在windows环境下后缀为.exe)。
2.2数据文件
文件的内容不一定是程序,而是程序在运行时读取的数据,列如程序运行需要读取的文件数据或者是输出内容的文件。
2.3文件名称
文件名称是方便用户识别和使用。
文件名称包含3个部分:文件路径+文件名主干+文件后缀
列如 D:\work\data.txt 为了方便一般都叫文件名。
3.二进制文件和文本文件
依据数据的组织形式,数据文件被称为文本文件或二进制文件。
3.1二进制文件
数据在内存中以二进制的形式储存,在输出到外存的文件时不进行转换的就是二进制文件
3.2文本文件
如果要求在外存上以ASCII码的形式存储,就需要在存储前转换。以ASCII码的形式存储的文件就是文本文件。
3.3一个数据在文件如何存储?
字符全部以ASCII码的形式存储,数值型两种都可以存储
代码测试一下
#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
int main()
{
int a = 10000;
FILE * pf = fopen("test.txt", "wb");//打开文件
if (pf == NULL)
{
perror(fopen);//用来报错误的
return 1;
}
fwrite(&a, 4, 1, pf);//以二进制写到文件中
fclose(pf);//关闭文件
pf = NULL;//防止出现野指针
return 0;
}
我们把10000储存进去在记事本打开是这样的?看不懂 所以我们就要换另外一种方法
虽然是二进制 但是它显示的是16进制!!
4.文件的打开和关闭
上面的代码就出现了文件的打开和关闭,只不过要用函数。
在介绍文件的打开和关闭要知道一些东西 讲起来比较抽象,晦涩难懂。
4.1流和标准流
4.1.1流
我们程序的数据需要输出到各种外部设备,也需要从外部设备获取数据,不同的外部设备的输入输出操作各不相同,为了方便程序员对各种设备进行方便的操作,我们抽象出了流的概念,我们可以把流想象成流淌着字符的河。C程序针对文件、画面、键盘等的数据输入输出操作都是通过流操作的。一般情况下,我们要想向流里写数据,或者从流中读取数据,都是要打开流,然后操作。
4.1.2标准流
那为什么我们从键盘输入数据,向屏幕上输出数据,并没有打开流呢?
那是因为C语言程序在启动的时候,默认打开了3个流
stdin-标准输入流,在大多数的环境中从键盘输入,scanf函数就是从标准输入流中读取数据。stdout-标准输出流,大多数的环境中输出至显示器界面,printf函数就是将信息输出到标准输出流中。
stderr-标准错误流,大多数环境中输出到显示器界面。
这是默认打开了这三个流,我们使用scanf、printf等函数就可以直接进行输入输出操作的。stdin、stdout、stderr三个流的类型是:FILE*,通常称为文件指针。
C语言中,就是通过FTLE*的文件指针来维护流的各种操作的。
4.2文件指针
文件类型的指针,简称”文件指针”。每个被使用的文件都会在内存中开辟一个文件信息区,用来存放。这些信息保存在一个结构体变量中,该结构体被系统命名为 FILE 。
不同的编译器 FILE 的内容包含不一样,大多都相同。
我们一般都FILE*这个指针来对FILE 结构体维护。也就是我们可以通过FILE * 这个指针来间接的找到与文件有关联的文件。
举个栗子:
4.3文件打开和关闭
文件读写前要打开文件,使用结束后要关闭文件。
在ANSIC 规定使用 fopen函数来打开文件,fclose来关闭文件。
其中fopen中的参数mode 表示文件的打开模式,下面是一些打开方式
给大家上代码演示一下,要注意一下文件打开模式。
struct S
{
char arr[20];
int age;
float score;
};
int main()
{
struct S s = {"李四",18,58.5f};
//把s写进文件中
FILE* pf = fopen("data.txt","w");
if (pf == NULL)
{
perror("fopen");
return 1;
}
//以文本的形式写进去的
fprintf(pf,"%s %d %f",s.arr,s.age,s.score);//这是后面会介绍的一种函数
fclose(pf);
pf = NULL;
return 0;
}
我们就把结构体里面的数据写上去了。
5.文件的顺序读写
5.1顺序读写函数介绍
这里函数怎么用会单独出一篇博客,这里就是罗列一下。
6.文件的随机读写
6.1 fseek
这个函数是根据指针的位置和偏移量来定位文件指针。
int fseek (FILE * stream,long int offset,int origin);
FILE * stream 是文件指针 , long int offset 是 偏移量 ,int origin 是起始位置
一些特定的参数!!!!
6.2 ftell
返回文件指针相对于指针的偏移量
long int ftell(FILE * stream);
6.3 rewind
让文件指针的位置回到文件起始位置
void rewind(FILE * stream);
7. 文件读取结果的判定
7.1被错误使用的feof
切记:在文件读取过程中,不能用feof函数的返回值直接判断文件的是否结束。
作用:文件读取结束的时候,判断是读取结束的原因是否遇到文件末尾。
1.文本文件读取是否结束,判断返回值是否为 EOF 或者 NULL
fgetc用来判断是否为 EOF。
fgets用来判断是否为 NULL。
2.二进制文件读取结束判断,判断返回值是否小于实际读取的个数。
fread 判断返回值是否小于实际读取的个数。
8.文件缓冲区
ANSIC标准采用“缓冲文件系统”处理的数据文件的,所谓缓冲文件系统是指系统自动地在内存程序中每一个正在使用的文件开辟一块“文件缓冲区”。从内存向磁盘输出数据会先送到内存中冲区,装满缓冲区后才一起送到磁盘上。如果从磁盘向计算机读入数据,则从磁盘文件中读取数入到内存缓冲区(充满缓冲区),然后再从缓冲区逐个地将数据送到程序数据区(程序变量等)。缓冲区的大小根据C编译系统决定的。
先给结论:因为有缓冲区的存在,C语言在文件操作时,需要做刷新缓冲区或者在文件操作结束的时候关闭文件。如果不做,可能导致读写文件的问题。
后言
这篇博客顺序读写函数使用和文件随机读写里面的三个函数都会在下一篇博客里面介绍。主要是本恐龙有点懒了!!哈哈哈