5.文件的随机读写
5.1.fseek
知识点:
int fseek ( FILE * stream, long int offset, int origin );
改变文件指针的指向
stream是文件信息区
offset是偏移量
origin是起始位置
起始位置可以是一下三种,SEEK_SET文件的开始、SEEK_CUR文件当前的位置、SEEK_END文件的末尾
细节:
通过实例来具体的解释
int main() { //省略写的步骤直接创建一个文件写好后直接使用 FILE* pf = fopen("test.txt", "r"); if (NULL == pf) { perror("fopen"); return 0; } int ch = fgetc(pf); printf("%c\n", ch);//a ch = fgetc(pf); printf("%c\n", ch);//b ch = fgetc(pf); printf("%c\n", ch);//c //此时因为fgetc返回后会自动往后走一步 //所以若想重新打印a //则可以通过fseek函数来实现,此时指向d应该往后偏移3步 fseek(pf, -3, SEEK_CUR); ch = fgetc(pf); printf("%c\n", ch);//a return 0; }
5.2ftell
知识点:
long int ftell ( FILE * stream );
返回此时的偏移量
细节:
很简单直接通过代码解释
5.3.rewind
知识点:
void rewind ( FILE * stream );
回到文件起始的位置
细节:
当fseek向左偏移-2打印了b后再用rewind直接回到起始位置再进行打印出a
6.文本文件和二进制文件
知识点:
二进制文件:内存中的数据是以二进制的形式存储的,如果不加以如何转化直接存到外存的文件就叫做二进制文件
文本文件:内存中的数据存储在外存前,将二进制转化成ASCII码对应的字符后再存储的文件就叫做文本文件
细节:
具体来讲就是:当我们有数值10000此时他的二进制可表示成:
00000000 00000000 00100111 00010000
若直接吧上述的二进制序列直接存储在文件中的则是二进制文件
若是把10000 分解成 5个字符 : '1' 、 '0' 、'0' 、... 后再分别把这5个字符ASCII码值进行存储的话就被称为文本文件
1ASCII码值: 49的二进制:00110001
0ASCII码值:48的二进制: 00110000 的二进制
7.文件读取结束的判定
7.1.feof函数
知识点:
当文件读取结束后可以用feof函数是用来判断读取失败的原因
细节:
fgetc读取失败返回EOF,成功返回该字符
fgets读取失败时返回NULL,把str返回(str是所要放字符串的起始位置)
fread返回实际读到的个数,所以可以通过判断返回值是否小于实际要读的个数来判断是否正确
在文件读取结束后,为了知道原因我们可以
ferror(pf)
判断是不是读取时遇到(I / O输入输出型) 错误而结束的,如果是则返回真
puts("I/O error when reading");
feof(fp))
判断是不是遇到结束标志而结束的,如果是则返回真
puts("End of file reached successfully");
具体练习:
#include <stdio.h> enum { SIZE = 5 }; int main(void) { double a[SIZE] = {1.,2.,3.,4.,5.}; FILE *fp = fopen("test.bin", "wb"); // 必须用二进制模式 fwrite(a, sizeof *a, SIZE, fp); // 写 double 的数组 , sizeof *a 表示的是一个元素的大小 fclose(fp); double b[SIZE]; fp = fopen("test.bin","rb"); size_t ret_code = fread(b, sizeof *b, SIZE, fp); // 读 double 的数组 if(ret_code == SIZE) { puts("Array read successfully, contents: "); for(int n = 0; n < SIZE; ++n) printf("%f ", b[n]); putchar('\n'); } else { // error handling if (feof(fp)) printf("Error reading test.bin: unexpected end of file\n"); else if (ferror(fp)) { perror("Error reading test.bin"); } } fclose(fp); }
8.文件缓冲区
知识点:
ANSIC 标准采用“缓冲文件系统”处理的数据文件的,所谓缓冲文件系统是指系统自动地在内存中为程序中每一个正在使用的文件开辟一块“文件缓冲区”。从内存向磁盘输出数据会先送到内存中的缓冲区,装满缓冲区后才一起送到磁盘上。如果从磁盘向计算机读入数据,则从磁盘文件中读取数据输入到内存缓冲区(充满缓冲区),然后再从缓冲区逐个地将数据送到程序数据区(程序变量等)。缓冲区的大小根据C编译系统决定的。
只有当缓冲区满了或者自动刷新缓冲区(fflush(pf);函数刷新缓冲区、当fclose关闭文件时才也会刷新缓冲区)才能让数据从缓冲区去到数据区或文件 。
所以我们一定要关闭文件,否则有可能没有把数据存进文件中
本章完。预知后事如何,暂听下回分解。