目录
在本章学习前,我们需要了解两个计算机硬件——1.内存,2.硬盘。我们在C语言编辑器上敲写的代码都是存放在内存中。本章中,将重点讲述如何将内存中的数据存储在硬盘中的文件内,和如何读取出硬盘中的文件。
1.什么是文件
1.1 文件的概念
C语言中,文件就是存储在磁盘上的文件。
1.2 文件名
文件名:文件路径 \ 文件名 . 扩展名
例如:C:\wenjian\test.obj ,这就是一个文件名。
2.为什么用使用文件
现阶段,我们在初学C语言中,敲写代码执行程序都是在IDE(集成开发环境)中进行的,所以我们的数据都是存放在内存中的,当程序结束时,内存就会被释放清理,数据也就消失。所以,当我们想要长期存储数据时,C语言就提供了这么一种功能。
3.文件的分类
3.1 程序文件 和 数据文件
3.1.1 程序文件
我们创建的 源文件(.c),当执行我们代码时,生成的 目标文件(.obj),编译连接后的 可执行文件(.exe),都是我们的程序文件。
3.1.2 数据文件
数据文件中的内容不一定是程序。当我们想要向硬盘存储数据时,或从硬盘中读写数据时,都是在数据文件中操作的。数据文件又分为 二进制文件 和 文本文件。
本章,也只讲解数据文件在C语言中的运用
3.2二进制文件 和 文本文件
3.2.1 二进制文件:
在内存中存储的都是机器识别的二进制数字,如果我们不作任何转换,将内存数据直接存放到外存(硬盘),那么在硬盘中的文件,也就成为二进制文件。
3.2.2 文本文件:
文本文件在外存中以ASCII码的形式存储,在存储前,进行转换。
4.文件的打开和关闭
4.1 流
程序需要从外部设备中获得数据,也需要将数据输出到外部设备,由于对各种外设的操作不同,我们就抽象出了 " 流 " 的概念。
当我们需要数据时,就从流获得,输出就向输出。但我们首先需要打开 流,才能进行操作。在C语言中,对文件,画面以及键盘的数据输入输出都是同流操作。
4.2 标准流
其实我们一直都在使用流,想想我们使用键盘向程序写入变量的值,这时我们就是用了标准流。在C语言中,我们默认打开了3个标准流。
• stdin - 标准输入流,在大多数的环境中从键盘输入。
• stdout - 标准输出流,大多数的环境中输出至显示器界面。
4.3 文件指针
在程序中,每次被使用的文件,都会开辟一个文件信息区,这是一个结构体变量,里面包含了各种文件信息,被重命名为 FILE 。这是包含在 stdio.h的头文件中。
struct _iobuf {
char *_ptr;
int _cnt;
char *_base;
int _flag;
int _file;
int _charbuf;
int _bufsiz;
char *_tmpfname;
};
typedef struct _iobuf FILE;
我们通过 FILE*的指针来读写这个文件,我们通过文件指针变量能间接找到与之相关联的文件信息。
下面我们创建一个FILE*的指针
FILE* pf; //文件指针变量
4.4 文件的打开和关闭
与动态内存管理相似,我们在打开文件时后,应关闭文件,因为我们能打开的文件数有限。
//打开⽂件
FILE * fopen ( const char * filename, const char * mode );
//filename 就是文件名
//mode 是文件打开模式
//关闭⽂件
int fclose ( FILE * stream );
//stream就是流,也可以理解为文件指针
文件的打开模式(mode):
5.文件的顺序读写
因为需要文件展示,所以如下代码结果均以图片展示为主。
5.1 futc 和 fgetc
int fputc ( int character, FILE * stream ); //fputc的使用
int fgetc ( FILE * stream ); //fgetc的使用
1.fputc
2.fgetc
5.2 fputs 和 fgets
int fputs ( const char * str, FILE * stream ); //fputs的使用
char * fgets ( char * str, int num, FILE * stream ); //fgets的使用
1.fputs
2.fgets
5.3 fprintf 和 fscanf
int fprintf ( FILE * stream, const char * format, ... );
// fprintf的使用
int fscanf ( FILE * stream, const char * format, ... );
//fscanf的使用
1.fprintf2.fscanf
5.4 fwrite 和 fread
size_t fwrite ( const void * ptr, size_t size, size_t count, FILE * stream );
// fwrite的使用
size_t fread ( void * ptr, size_t size, size_t count, FILE * stream );
// fread的使用
1.fwrite
2.fread
6.文件的随机读写
6.1 fseek
根据文件指针的位置和偏移量来定位文件指针。
int fseek ( FILE * stream, long int offset, int origin );
//stream 就是文件指针,也就是流
//offset 就是文件指针的偏移量
//origin 就是文件的起始地址,有三种模式
// 1.SEEK_SET 从起始地址算偏移量
// 2.SEEK_CUR 从当前文件地址算偏移量
// 3.SEEK_END 从末位算偏移量
6.2 ftell
返回文件指针相对于起始位置的偏移量
long int ftell ( FILE * stream );
6.3 rewind
让文件指针的位置回到文件的起始位置
void rewind ( FILE * stream );
7.文件结束的判定
被错误使用的feof。feof作用是,当文件结束时,判断文件结束是否为正常结束,遇到文件尾结束。
1. 文本文件读取是否结束,判断返回值是否为 EOF ( fgetc ),或者 NULL ( fgets )
例如:
• fgetc 判断是否为 EOF 。
• fgets 判断返回值是否为 NULL 。
8.文件缓冲区
ANSIC 标准采用“缓冲文件系统”处理的数据文件的,所谓缓冲文件系统是指系统自动地在内存中为程序中每⼀个正在使用的文件开辟⼀块“文件缓冲区”。从内存向磁盘输出数据会先送到内存中的缓冲区,装满缓冲区后才⼀起送到磁盘上。如果从磁盘向计算机读入数据,则从磁盘文件中读取数据输入到内存缓冲区(充满缓冲区),然后再从缓冲区逐个地将数据送到程序数据区(程序变量等)。缓冲区的大小根据C编译系统决定的