Presentation is loading. Please wait.

Presentation is loading. Please wait.

第十三章 文件 目录 学生信息管理系统的完善 文件的概念 文件类型指针 文件的打开与关闭 文件的顺序读写

Similar presentations


Presentation on theme: "第十三章 文件 目录 学生信息管理系统的完善 文件的概念 文件类型指针 文件的打开与关闭 文件的顺序读写"— Presentation transcript:

1 李祥 E-mail:tom_lx@126.com QQ:100756

2 第十三章 文件 目录 1 2 3 4 5 6 7 学生信息管理系统的完善 文件的概念 文件类型指针 文件的打开与关闭 文件的顺序读写
文件的定位、测试与随机读写函数 7 文件操作的出错检测

3 知识点要求: 技能要求: 教学要求 1 2 3 1 2 文件和文件指针的概念 文件的打开、关闭、读写等文件操作函数 文件的出错检测函函数
掌握文件的顺序读写和随机读写 2 掌握文件文件操作的出错检测

4 13.1 学生信息管理系统的完善 任务描述: 将学生信息管理系统中的学生信息以文件形式长期保存下来。 任务要求:
(1)编写saveInfo函数,将学生信息存放到硬盘。 (2)编写loadInfo函数,将存放在硬盘上的学生信息读入内存中。

5 13.1 学生信息管理系统的完善 任务分析: (1)将学生信息长期保存下来,涉及到文件有关操作。
(2)对文件进行操作,要分为三个步骤:打开、读写、关闭。

6 13.1 学生信息管理系统的完善 涉及知识点 文件的概念 文件的打开和关闭 文件的读写操作 文件的出错检测

7 13.2 文件的概念 文件实际上是指存放在外部存储器上的数据的集合,它具有一个唯一的名字(文件名),可以通过文件名对文件进行存取、修改和删除等操作。 C语言把文件看成是一个字符(字节)的序列,即由一个一个字符(字节)的数据顺序组成,根据数据的组织形式,可以分为ASCII文件和二进制文件。

8 13.2 文件的概念 一个数10000,在内存中占2个字节,但如果按ASCII形式,则占5个字节,而按二进制文件系统,则占2个字节。
一个C文件是一个字符流或二进制流。即C语言文件不是由记录组成的,而是以字节(字符)为单位进行存放的,我们把这种文件称为流式文件。

9 13.2 文件的概念 ANSI C标准采用“缓冲文件系统”处理数据文件。所谓缓冲文件系统是指系统自动地在内存中为每个正在使用的文件名开辟一个缓冲区,从内存向磁盘输出数据必须先送到内存中的缓冲区,装满后才一起送到磁盘中去,从磁盘向内存输入数据也是类似。

10 13.3 文件类型指针 每个正在被使用的文件都在内存中占一个空间,用来存放文件的有关信息,这些信息保存在一个结构体变量中,该结构体类型在stdio.h中有说明,系统定义其为FILE。

11 13.3 文件类型指针 typedef struct { short level; //缓冲区空或满的程度
unsigned flags; //文件状态标志 char fd; //文件描述符 unsigned char hold; //如果缓冲区无内容不读字符 short bsize; //缓冲区大小 unsigned char *buffer;//数据缓冲区位置 unsigned char *curp;//当前指针位置 unsigned istemp;//临时文件指示器 short token; //用于有效性检查 } FILE;

12 13.3 文件类型指针 FILE *fp; 则fp就是一个指向FILE类型结构的指针变量,这就是文件类型指针,通过文件指针就可对它所指的文件进行访问。 对文件的操作一般分三个步骤:打开文件,读或写文件,关闭文件。

13 13.4 文件的打开与关闭 1. 文件的打开函数(fopen)
fopen函数表示将给用户指定的文件在内存中分配一个FILE结构区,并将该结构的指针返回给用户程序。 格式: FILE *fp; fp=fopen(文件名,使用文件方式);

14 Mode 含 义 文件类型 "r" 打开已经存在的文件,用于只读 文本文件 "w" 创建或重建文件,用于只写,若文件已存在则重建 "a" 在文件尾部增加数据,若文件不存在则创建后用于只写 "rb" 打开已存在文件,用于只读 二进制文件 "wb" "ab" "r+" 打开已存在的文件,用于读写 "w+" 创建或重建文件,用于读写,若文件已存在则重建 "a+" 在文件尾部增加数据,若文件不存在,则创建后用于读写 "r+b" "w+b" "a+b" r—read(读) w—write(写) a—append(追加) b—binary(二进制) +—(读和写)

15 13.4 文件的打开与关闭 如果不能实现“打开”任务,fopen函数将返回一个出错信息,此时将返回一个空指针值NULL。
常用下面的方法打开一个文件: FILE *fp; if((fp=fopen("c:\\data.txt","w"))==NULL) { printf("无法打开此文件! \n "); exit(0); }

16 13.4 文件的打开与关闭 2.文件的关闭函数(fclose)
在使用完一个文件后应该关闭它,这样做的目的是为了防止它再被误用。“关闭”就是使文件指针变量不指向该文件,即与文件“脱钩”。 格式:fclose (文件指针);

17 13.4 文件的打开与关闭 如果关闭成功,则返回0,否则返回一个非0值。 可用下面的方法测试: if(fclose(fp)!=0) {
printf("无法关闭此文件! \n "); exit(0); } else printf("此文件已关闭! \n ");

18 【例13.1】测试正确的文件打开和关闭方式。 #include<stdio.h> #include<stdlib.h> void main() { FILE *fp; if((fp=fopen("c:\\data.txt","w"))==NULL) { printf("无法打开此文件!\n"); exit(0); } else printf("此文件已打开!\n");

19 printf("在打开文件和关闭文件之间,可以读写文件......\n");
if(fclose(fp)!=0) { printf("无法关闭此文件! \n"); exit(0); } else printf("此文件已关闭! \n"); return;

20 13.5 文件的顺序读写 主要的顺序读写函数有以下4对: 读写字符函数fputc和fgetc 读写字符串函数fputs和fgets
格式化读写函数fscanf和fprintf 二进制读写函数fread和fwrite

21 13.5 文件的顺序读写 13.5.1读写字符函数 (1)fputc函数 格式:char fputc(char ch,FILE *fp);
功能:将一个字符写入到磁盘文件中去。 (2)fgetc函数 格式:char fgetc(FILE *fp); 功能:从指定的打开的文件流中读取一个字符。

22 13.5 文件的顺序读写 【例13.2】从键盘上接收任意多个字符,分别输出到显示器和磁盘文件test.txt中,直到输入"#"为止。

23 #include<stdio.h>
#include<stdlib.h> void main( ) { FILE *fp; char ch; if ((fp=fopen("c:\\test.txt","w"))==NULL) {printf("无法打开此文件!\n "); exit(0); } printf("请输入一些字符,以\"#\"结束:\n"); ch=getchar(); while(ch!='#') {putchar(ch); fputc(ch,fp); //将字符数据输出到fp所指向的磁盘文件 } printf("\n已经写入文件,这是显示器输出效果。\n"); fclose(fp); return;

24 13.5 文件的顺序读写 【例13.3】将例13.2写入到磁盘文件test.txt中的内容读出来输出到显示器,并复制到另一个磁盘文件testdes.txt中。

25 #include<stdio.h>
#include<stdlib.h> void main( ) { FILE *fin,*fout; char ch; if ((fin=fopen("c:\\test.txt","r"))==NULL) { printf("无法打开此文件!\n "); exit(0); } if ((fout=fopen("c:\\testdes.txt","w"))==NULL)

26 ch=fgetc(fin); while(!feof(fin)) //feof()是测试文件结尾的函数 { fputc(ch,fout); putchar(ch); } printf("\n读写完毕,这是显示器输出效果。\n"); fclose(fin); fclose(fout); return;

27 13.5 文件的顺序读写 13.5.2读写字符串函数 (1) fputs函数
格式:int fputs(char *str, FILE *fp); 功能:向文件写入字符串。 说明: ①该函数将str指向的字符串内容(不包括’\0’)输出到fp指向的文件,其中,str是字符串首地址,fp是文件指针变量。 ②函数返回值:输出成功,返回一个非负数;输出失败,返回EOF。

28 13.5 文件的顺序读写 (2) fgets函数 格式:char *fgets(char *str, int n, FILE *fp);
功能:从文件中读取字符串。 说明: ①从fp指向的文件读取n-1个字符,放到以str为起始地址的存储空间,若在n-1个字符前遇到回车换行符或文件结束符,则读操作结束,并在读入的字符串后自动加一个’\0’。 ②函数返回值:输入成功,返回值为str的值,否则返回NULL。

29 13.5 文件的顺序读写 【例13.4】用字符串输入方式将键盘上输入的若干行字符串保存到文本文件file1.txt。

30 #include<stdio.h>
#include<stdlib.h> #include<string.h> void main( ) { FILE *fin; char w[81]; if ((fin=fopen("c:\\file1.txt","w"))==NULL) {printf("无法打开此文件!\n "); exit(0); } while(strlen(gets(w))>0) { fputs(w,fin); fputs("\n",fin); printf("文件写入完毕。\n"); fclose(fin); return;

31 13.5 文件的顺序读写 【例13.5】用字符串读取方式将例13.4中file1.txt的内容输出到屏幕,并将其内容复制到另一个文本文件file2.txt。

32 #include<stdio.h>
#include<stdlib.h> #include<string.h> void main( ) { FILE *fin,*fout; char w[81]; if ((fin=fopen("c:\\file1.txt","r"))==NULL) { printf("无法打开此文件!\n "); exit(0); } if ((fout=fopen("c:\\file2.txt","w"))==NULL)

33 while(fgets(w,80,fin)) { fputs(w,fout); printf("%s",w); } printf("文件读完毕,这是显示器输出效果。\n"); fclose(fin); fclose(fout); return;

34 13.5 文件的顺序读写 13.5.3格式化读写函数 对应于格式化输入输出函数scanf和printf,C语言还提供了缓冲型格式化输入输出函数,即fscanf( )和fprintf( )函数。 这四个函数都是格式化读写函数,但是有一点不同,即:fprintf和fscanf函数的读写对象不是终端而是磁盘文件。

35 13.5 文件的顺序读写 调用格式如下: fscanf(FILE *fp,char *format, arg_list);
fprintf(FILE *fp,char *format, arg_list); 说明: (1)fp为文件指针变量,format为格式字符串,arg_list为输入/输出表列。 (2)fscanf的作用是按照format给出的格式字符串,把从fp中读取的内容分别赋给变量arg1,arg2,…argn;fprintf的作用是按照format给出的格式字符串,将变量arg1,arg2,…argn的值写入到fp指向的文件中。

36 13.5 文件的顺序读写 (3)这两个函数由于在输入时要将ASCII码转为二进制,在输出时又要将二进制转为ASCII码,所以文件操作时间花费较大,所以一般情况不建议使用,而采用fread和fwrite函数。

37 13.5 文件的顺序读写 13.4.4二进制读写函数 在程序中常常要求一次读写一组数据,如数组或者结构体变量的值,C语言允许用fread函数从文件中读一个数据块,用fwrite函数向文件写一个数据块,用它们来进行块读写操作,在读写时以二进制形式进行。

38 13.5 文件的顺序读写 二进制读写函数的调用形式如下: fread(buffer,num_bytes, count,fp);
fwrite(buffer,num_bytes, count,fp); 其中: (1)buffer是被读写数据的指针(地址),对于fread来说, 它是用来存放从文件读入的数据的存储区的地址 ,而对于fwrite来说,是要把此地址开始的存储区中的数据向文件输出; (2)num_bytes是一次读写的数据的字节数; (3)count是确定要读写的数据块的个数; (4)fp是文件指针变量;

39 13.5 文件的顺序读写 说明:用二进制读写方式按照内存中物理存储方式读写,不需要ASCII码和二进制之间的转换,读写效率比文本读写方式高。二进制文件不能像文本文件那样用记事本打开看到里面的详细信息,只能通过该二进制文件的读程序查看其信息。

40 13.5 文件的顺序读写 【例13.6】 从键盘输入10个学生的有关数据,然后把它们转存到磁盘文件上去。 解题思路:
定义有10个元素的结构体数组,用来存放10个学生的数据 从main函数输入10个学生的数据 用save函数实现向磁盘输出学生数据 用fwrite函数一次输出一个学生的数据

41 #include <stdio.h> #define SIZE 10 struct Student_type { char name[10]; int num; int age; char addr[15]; }stud[SIZE];

42 当前路径下的文件 void save( ) { FILE *fp; int i; if((fp=fopen("stu.dat","wb"))==NULL) { printf("cannot open file\n"); return; } for(i=0;i<SIZE;i++) if(fwrite(&stud[i], sizeof(struct Student_type), 1,fp)!=1) printf("file write error\n"); fclose(fp); =33,实际上 开辟36字节,是4的倍数

43 int main() { int i; printf(“enter data of students:\n"); for(i=0;i<SIZE;i++) scanf("%s%d%d%s", stud[i].name,&stud[i].num, &stud[i].age,stud[i].addr); save( ); return 0; }

44 13.5 文件的顺序读写 为了验证在磁盘文件“stu.dat”中是否已存在此数据,可以用以下程序从“stu.dat”文件中读入数据,然后在屏幕上输出。

45 #include <stdio. h> #include <stdlib
#include <stdio.h> #include <stdlib.h> #define SIZE 10 struct Student_type { char name[10]; int num; int age; char addr[15]; }stud[SIZE];

46 int main( ) {int i; FILE. fp; if((fp=fopen("stu
int main( ) {int i; FILE *fp; if((fp=fopen("stu.dat","rb"))==NULL) {printf("cannot open file\n"); exit(0); } for(i=0;i<SIZE;i++) {fread (&stud[i],sizeof(struct Student_type),1,fp); printf (“%-10s %4d %4d %-15s\n”, stud[i].name,stud[i].num, stud[i]. age,stud[i].addr); } fclose (fp); return 0;

47 13.6 文件的随机读写 到目前为止,我们介绍的磁盘文件操作的例子都是顺序读写的,即从文件当前位置,依次连续地读写一定长度的数据,容易操作,但有时效率不高,比如文件中有很多的学生数据,希望修改中间的某个学生的信息,必须先逐个读入它前面的数据,这时希望允许用户从任意位置读写任意数据,即随机读写。

48 13.6 文件的随机读写 磁盘文件操作时涉及的相关术语如下: (1)文件头:磁盘文件数据开始位置。
(2)文件尾:磁盘文件数据结束之后的位置。 (3)文件当前位置指针:也称为文件读写位置标 记或文件指针,指向文件中下一个被读写的字节 (4)文件出错标记:文件操作出错时,系统在文件流的控制结构中设置的文件出错标记。

49 13.6 文件的随机读写 (1) rewind( )函数 格式:rewind(FILE *fp);
功能:将文件指针返回文件头,同时清除文件结束符和出错标记。

50 13.6 文件的随机读写 (2)feof()函数 格式:feof(FILE *fp); 功能:测试文件指针是否到达文件结尾。
说明:当文件指向文件结尾时,该函数返回一个非0值,表明文件数据结束,否则返回0以表明文件未结束。

51 13.6 文件的随机读写 (3)ftell()函数 格式:ftell(FILE *fp);
功能:测试文件指针的当前值 ,这个值是从文件头算起的字节数 。

52 13.6 文件的随机读写 字节数 (4) fseek( )函数
格式:fseek(FILE *fp,long num_bytes,int origin) 功能:随机设置文件指针的值,以实现文件的随机读取。 例:fseek(fp,100L,0); //将文件指针从文件头向文件尾移动100个字节 fseek(fp,50L,1); //将文件指针从当前位置向文件尾移动50个字节 fseek(fp,-50L,2); //将文件指针从文件尾向后退即向文件头方向移动50个字节

53 13.6 文件的随机读写 【 例13.7】 在磁盘文件上存有10个学生的数据。要求将第1,3,5,7,9个学生数据读入计算机,并在屏幕上显示出来。 要求:从【例13.6】中建立的“stu.dat”中读入数据

54 13.6 文件的随机读写 解题思路: 按二进制只读方式打开文件 将文件位置标记指向文件的开头,读入一个学生的信息,并把它显示在屏幕上
再将文件标记指向文件中第3,5,7,9个学生的数据区的开头,读入相应学生的信息,并把它显示在屏幕上 关闭文件

55 #include<stdio. h> #include <stdlib
#include<stdio.h> #include <stdlib.h> struct St { char name[10]; int num; int age; char addr[15]; }stud[10];

56 int main() { int i; FILE. fp; if((fp=fopen(“stu
int main() { int i; FILE *fp; if((fp=fopen(“stu.dat”,“rb”))==NULL) { printf("can not open file\n"); exit(0); } for(i=0;i<10;i+=2) { fseek(fp,i*sizeof(struct St),0); fread(&stud[i], sizeof(struct St),1,fp); printf(“%-10s %4d %4d %-15s\n”, stud[i].name,stud[i].num, stud[i].age,stud[i].addr); } fclose(fp); return 0;

57 13.7 文件操作的出错检测 在进行磁盘文件操作时,可能会因为磁盘质量、驱动器等原因造成各种错误。为了避免这些错误带来的其他严重后果,我们要及时地进行检错与处理。

58 13.7 文件操作的出错检测 (1) ferror( )函数
除了从磁盘操作函数的返回值可以判断操作是否成功以外,我们还可以用函数来检测文件操作过程中是否出现错误,其具体用法如下: 格式:ferror(FILE *fp); 功能:检测文件操作是否出错。

59 13.7 文件操作的出错检测 (2) clearerr( )函数 格式:void clearerr(FILE *fp);
功能:将指定的文件的出错标记和文件结束标记置0。 (3) exit( )函数 格式:void exit(int status); 功能:关闭文件。

60 课堂练习 1.由终端键盘输入字符,存放到文件中去,用!结束输入。完善程序。 #include <stdio.h>
#include <stdlib.h> int main() { FILE *fp; char ch,fname[10]; printf("Input name of file\n"); gets(fname); if((fp=______________)==NULL) //以只写文本文件的方式打开 { printf("cannot open this file!\n"); exit(0); } printf("Enter data:\n"); while ____________ fputc(____); fclose(fp); return 0; }

61 本章小结 重点: 1 文件的打开和关闭 2 文件的顺序读写 难点: 1 文件的随机读写

62 本章结束!


Download ppt "第十三章 文件 目录 学生信息管理系统的完善 文件的概念 文件类型指针 文件的打开与关闭 文件的顺序读写"

Similar presentations


Ads by Google