文件缓冲区
ANSIC 标准采用“缓冲文件系统”处理的数据文件的,所谓缓冲文件系统是指系统自动地在内存中为程序中每一个正在使用的文件开辟一块“文件缓冲区”。从内存向磁盘输出数据会先送到内存中的缓冲区,装满缓冲区后才一起送到磁盘上。如果从磁盘向计算机读入数据,则从磁盘文件中读取数据输入到内存缓冲区(充满缓冲区),然后再从缓冲区逐个地将数据送到程序数据区(程序变量等)。缓冲区的大小根据C编译系统决定的。
文件指针
缓冲文件系统中,关键的概念是“文件类型指针”,简称“文件指针”。
每个被使用的文件都在内存中开辟了一个相应的文件信息区,用来存放文件的相关信息(如文件的名字,文件状态及文件当前的位置等)。这些信息是保存在一个结构体变量中的。该结构体类型是有系统声明的,取名FILE.
每当打开一个文件的时候,系统会根据文件的情况自动创建一个FILE结构的变量,并填充其中的信息,使用者不必关心细节。
文件开闭函数
ANSIC规定使用fopen函数打开文件,fclose函数关闭文件
FILE* fopen(const char* filename, const char* mode);
int fclose(FILE* stream);
mode | 功能 | 如果指定文件不存在 |
---|---|---|
r | 只读 文本文件 | bug |
w | 只写 文本文件 | 建立一个新文件 |
a | 追加 文本文件 | bug |
rb | 只读 二进制文件 | bug |
wb | 只写 二进制文件 | 建立一个新文件 |
ab | 追加 二进制文件 | bug |
r+ | 读写 文本文件 | bug |
w+ | 读写 文本文件 | 建立一个新文件 |
a+ | 追加 文本文件 | 建立一个新文件 |
rb+ | 追加 二进制文件 | bug |
wb+ | 只写 二进制文件 | 建立一个新文件 |
ab+ | 追加 二进制文件 | 建立一个新文件 |
文件输入输出函数
函数名 | 功能 | 适用流 |
---|---|---|
fgetc | 字符输入函数 | 所有输入流 |
fputc | 字符输出函数 | 所有输出流 |
fgets | 文本行输入函数 | 所有输入流 |
fputs | 文本行输出函数 | 所有输出流 |
fscanf | 格式化输入函数 | 所有输入流 |
fprintf | 格式化输出函数 | 所有输出流 |
fread | 二进制输入 | 文件流 |
fwrite | 二进制输出 | 文件流 |
字符形式读写
- fgetc( ):从指定的流中读取一个字符
读取成功时返回读取到的字符,读取到文件末尾或读取失败时返回EOFint fgetc (FILE *steam);
- fputs( ):向指定的流写入中一个字符
fputc() 写入成功时返回写入的字符,失败时返回 EOFint fputc ( int ch, FILE *steam);
字符串形式读写
- fgets( ):从指定的流中读取一个字符串
读取成功时返回字符数组首地址,也即 str;读取失败时返回 NULLchar* fgets (char *str, int n, FILE *steam);
- fputs( ):向指定的流写入一个字符串
写入成功返回非负数,失败返回 EOFint fputc ( char* str, FILE *steam);
数据块形式读写
-
fread( ):从指定文件中读取块数据
size_t fread ( void *ptr, size_t size, size_t count, FILE *fp );
-
fwrite( ):向文件中写入块数据
size_t fwrite ( void * ptr, size_t size, size_t count, FILE *fp );
ptr:为内存区块的指针,它可以是数组、变量、结构体等。
- fread() 中的 ptr 用来存放读取到的数据,
- fwrite() 中的 ptr 用来存放要写入的数据。
size:表示每个数据块的字节数。
count:表示要读写的数据块的块数
返回值:返回成功读写的块数,即 count
格式化读写
- fscanf( )
int fscanf ( FILE * stream, const char * format, ... );
- fprintf( )
fscanf( ) 和 fprintf( )与 scanf()和 printf()相似,都是格式化读写函数,区别在于 fscanf() 和 fprintf() 的读写对象不是键盘和显示器,而是所有输入输出流。int fprintf ( FILE * stream, const char * format, ... );
文件的定位函数
随机读写方式需要将文件内部的位置指针移动到需要读写的位置再进行读写,这通常也被称为文件的定位。
- fseek( ):根据当前位置指针和偏移量来定位新的
第一个参数 fp 为文件指针;int fseek ( FILE * stream, long int offset, int origin )
第二个参数 offset 为偏移量,它表示要移动的字节数,整数表示正向偏移,负数表示负向偏移;
第三个参数 origin 表示设定从文件的哪里开始偏移,取值如下表
起始点 | 表示符号 | 数字表示 |
---|---|---|
文件首 | SEEK_SET | 0 |
当前位置 | SEEK_CUR | 1 |
文件末 | SEEK_END | 2 |
- ftell( ):返回当前读写位置相对于起始位置的偏移量
long int ftell ( FILE * stream );
- rewind( ):将读写位置重置到文件首
由于 rewind 函数没有返回值,所以我们很难判断“rewind(fp)”是否执行成功,应该尽量使用fseek代替rewindvoid rewind ( FILE * stream );
对EOF的说明
EOF 本来表示文件末尾,意味着读取结束,但是很多函数在读取出错时也返回 EOF,所以在返回EOF时,我们无法确定到底是文件读取结束还是文件读取错误,这时需要用到feof( )或ferror( )函数,来判断位置指针是否指向了文件末。
- foef( ):判断位置指针是否指向了文件末尾
int feof ( FILE * fp );
- ferror( ):判断文件操作是否出错
int ferror ( FILE * fp );