1、Rose 第六章 磁盘数据存储 济南大学 Rose 文件的引出 为什么使用文件存储数据? 前面的程序里,我们学习了数组类型,能够存储一批数据。有一个问题是,这些数据只有在程序运行过程中才存储在数组中的,当程序运行结束后,系统就释放数组的存储空间,数据将不能保存下来。如果下次操作仍然针对同样的一批数据,我们就不得不重新从键盘上输入这批数据或重新初始化数组了。还有一个问题,程序的运行结果都是输出到屏幕上的,程序运行结束后,结果并没有保存下来,如果希望每次都将程序输出到屏幕上的数据存储下来,应该怎么办呢? 这样就需要用到磁盘文件了。 我们可以用磁盘文件把程序的已知数据存储起来,需要的时候让程序从文件
2、里直接读取数据,而不需每次从键盘输入了。也可以将程序的运行结果写入文件中存起来。 济南大学 Rose 文件的分类 文本文件 和 二进制文件 1. 文本文件 中按字符存储内容,每一个字节存放一个 ASCII码,代表一个字符。也叫ASCII码文件。 2. 二进制文件 则是将数据按内存中的原样(二进制形式)存放在磁盘上。 济南大学 Rose 文件的分类举例 例如:存储 12345这个整数, 如果用文本文本文件存储,将存储 12345,共 5个数字字符,共占 5个字节。 如果用二进制形式存储,将存储 12345在内存中的二进制形式 11010100 00110001,共占 2个字节。 济南大学 Ros
3、e 显然:二进制文件占存储空间较小,但都是 0101 二进制代码,不直观;而文本文件占存储空间大,但直观可查看,可以用 Windows中的记事本程序或 DOS中的 TYPE命令直接查看。 内存中 文本文件 001 1010 1 001 1010 0 001 1001 1 001 1001 0 001 1000 1 1 1010 100 001 1000 1 5 4 3 2 1 二进制文件 1 1010 100 001 1000 1 济南大学 Rose 不论是二进制文件,还是文本文件,他们的文件操作都遵循同样的操作步骤,只不过打开文件的使用方式不同而已。 1.打开文件: fopen() 2.读写
4、文件: fscanf() 或 fprintf() 3.关闭文件: fclose() 济南大学 Rose #include main() char ch; FILE *fp; fp=fopen(“letter.dat“,“w“); if(fp=NULL) printf(“n Opening file error“); exit(0); for (ch=A;ch=Z;ch+) fputc(ch,fp); fputc(n,fp); fclose(fp); 例 1:将一串字符写入文件保存起来。 济南大学 Rose 文件使用总结和归纳: 1、先定义文件类型指针 2、使用 fopen() 函数打开或新建一
5、个文件。 3、检测文件打开是否成功。 4、向文件写入数据,或从文件读取数据。 5、使用 fclose() 函数关闭文件。 济南大学 Rose FILE 构造的文件类型 缓冲文件系统中,系统为每个正在被使用的文件都在内存中开辟一个区域,存放有关该文件的信息(如文件名、文件状态、当前位置等)。 C语言将这些信息保存在一个结构体变量中,该结构体类型是由系统在stdio.h中定义好的,取名为 FILE。 只需定义一个 FILE类型的 指针变量 ,通过该指针变量调用有关 文件操作函数 对指定文件进行操作。 济南大学 Rose 打开文件函数 fopen 对文件进行读写之前应当“打开”该文件,读写完毕之后应
6、当“关闭”该文件。 ANSI C规定使用 fopen函数来打开文件。 FILE *fopen(char *filename, char *mode); 其中, filename指定要打开的 文件名 ,可以使用字符串常量,也可以使用指向字符串的指针变量;mode表示文件的 使用方式 (见 215页)。 如前例中 fp=fopen(“letter.dat“,“w“); 济南大学 Rose 文件的使用方式 P215 读方式 r 写方式 w 追加方式 a 请务必记住! 济南大学 Rose 说明 1. 使用“ r”和 ” r+”时,文件应已经存在。 2. 使用“ w”和” w+”时, 新建一个文件 ,若
7、磁盘上已有同名文件,则被清除。 3. 使用“ a”和” a+”时,文件应已经存在,原有内容不被删除,位置指针移到数据末尾,可以添加内容。 如果操作的是二进制文件,在打开方式中加上字母“ b”。 济南大学 Rose 如果文件不在当前目录下,应该给出完整文件名描述,即包括文件存放的路径,如: fp=fopen(“d:roseletter.dat“,“w“); 注意赋值给定义的文件类型指针 fp 济南大学 Rose 文件关闭函数 fclose() 1. 文件使用完毕后,要释放文件缓冲区中的内容,将数据真正写入到磁盘文件中保存起来,因此必须使用 fclose() 函数关闭文件。 2. 如果使用文件完毕
8、没有正常的关闭该文件,容易引起数据的丢失。 3. 格式: fclose( fp) 济南大学 Rose 2 文件读写分类函数 我们使用文件的目的是为了存放数据,因此,对文件的操作主要可以分为两种: 读操作 和写操作 。读操作是从文件中读取数据;写操作是往文件中写数据,包括建立一个新文件、往文件中追加数据、插入数据或修改数据。 济南大学 Rose 单字符写入或读取函数 1. fputc函数 2. fgetc函数 例如: fputc( A, fp); 或 fputc( ch, fp); ch fgetc( fp) 此处 ch是字符变量 济南大学 Rose 字符串写入或读取函数 1. fputs函数
9、2. fgets函数 例如: fputs(“ hello”, fp); 或 fputs( str, fp); fgets( str, 长度, fp); 此处 str是字符数组名 济南大学 Rose 块数据,二进制数据写入或读取函数 1. fwrite函数 2. fread函数 例如: sy4borrow.c 中的 fread(books,sizeof(struct book),N,fp); fwrite(books,sizeof(struct book),N,fp); 此处 books是数组名 济南大学 Rose 格式化写入或读取函数 1. fprintf函数 2. fscanf函数 例如:
10、fprintf(fp, “ d: %.2f ”,i,score); fscanf(fp, “ d%f”, 济南大学 Rose 在读文本文件时,遇到回车符( r=13)换行 符 ( n=10) ,自动转换成 一个换行符 ;写时,反过来,将一个换行符转换成一个回车符和一个换行符(为了可以使用 TYPE命令显示其内容)。读写二进制文件则无此转换。 补充 济南大学 Rose 检测文件打开和其它文件使用函数 如果打不开文件(原因很多), fopen会返回空指针 NULL, 我们常用下面的方法检测文件是否打开: if(fp=NULL ) printf(“无法打开此文件! n”); exit(0); /*关
11、闭所有文件,终止此程序。*/ 济南大学 Rose 检测文件是否结束函数 feof feof(fp); 它用于检测位置指针是否到达了文件尾部。 返回非 0表示位置指针已到达文件尾。 返回 0表示位置指针未到达文件尾。 例如: ex10-5.c中 while(!feof(fp) sum=sum+student.score; fread( 济南大学 Rose 求文件指针当前位置函数 ftell ftell( fp) ; 返回位置指针相对于文件开头的位移量。 若出错返回 -1L。 例如: n ftell(fp); 济南大学 Rose 文件指针位置复位函数 rewind rewind( fp) ; 将文
12、件指针重拨回到文件开始处。 济南大学 Rose 文件指针定位函数 fseek int fseek(FILE *fp, long offset, int base); 功能:将文件的位置指针移到以 base为起始点,offset为位移量的位置,同时清除文件结束标志。 base常用三个符号常量: SEEK_SET、SEEK_CUR和 SEEK_END, 分别为 0、 1、 2常量值,分别表示文件开始、当前位置和文件末尾。 offset表示以起始点为基准,向前或向后移动的字节数(正、负)。 济南大学 Rose 例如 fseek(fp, 2, SEEK_SET); 表示将位置指针从文件开始处向后移动
13、2个字节。 fseek(fp, 2, SEEK_CUR); 表示将位置指针从当前位置向后移动 2个字节。 fseek(fp, -2, SEEK_END); 表示将位置指针从文件尾部向前移动 2个字节。 济南大学 Rose 例 6 输入一个文本文件名,要求显示该文件内容。显示完毕后,要求用户选择是否重新显示:当输入 Y时,重新显示该文件内容;如果按其它键,程序将正常结束。 济南大学 Rose 例 7 设二进制文件 letter.dat中顺序存放了一组字符,求顺序号为奇数的字符的 ASCII码之和。 济南大学 Rose 例 8 将 letter.dat文件存放的所有字符从显示器上显示出来。由于我们不知道文件中目前的字符个数,因此可以用 EOF作为循环的结束条件。 济南大学 Rose 实验 1、 建立一个文本文件 letter.dat, 从键盘上输入一串字符,写到该文件中,保存起来 3、 建立一个二进制文件 score.dat, 存放某班 32名同学某门课的成绩(每名同学要求有学号和成绩两个数据项。 2、 打开上题 建立的文本文件 letter.dat, 将该文件中的字符加密,加密算法采用上次实验的方法(即原字符 ASCII码值+4),将加密后的数据写入文件 4、打开上题 建立的二进制文件 score.dat, 求全班同学这门课的平均成绩。