Download presentation
Presentation is loading. Please wait.
1
第十章 文件操作
2
文件的基本概念 文件的基本函数 文件的顺序读写 文件的随机读写 文件的简单应用
本章要点 文件的基本概念 文件的基本函数 文件的顺序读写 文件的随机读写 文件的简单应用
3
10.1 C文件的有关概念 10.2 文件的打开与关闭 10.3 文件的顺序读写 10.4 文件的随机读写 10.5 文件读写的出错检测
主要内容 10.1 C文件的有关概念 10.2 文件的打开与关闭 10.3 文件的顺序读写 10.4 文件的随机读写 10.5 文件读写的出错检测
4
§10.1 C文件的有关概念 10.1.1什么是文件 所谓文件一般指存储在外部介质(如磁盘磁带)上 数据的集合.
操作系统是以文件为单位对数据进行管理的. 输入输出是数据传送的过程,数据如流水一样从 一处流向另一处,因此常将输入输出形象地称为 流(stream),即输入输出流。 C语言把文件看作是一个字符(字节)的序列, 即由一个一个字符(字节)的数据顺序组成。一 个输入输出流就是一个字节流或二进制流。
5
§10.1 C文件的有关概念 10.1.2 文件名 ↑ ↑ ↑ 一个文件要有一个惟一的文件标识,以便用户识 别和引用。文件标识包括三部分:
(1)文件路径:(2)文件名主干;(3)文件后缀。 文件路径表示文件在外部存储设备中的位置。 如: d: \ cc \ temp \ file1 . dat ↑ ↑ ↑ 文件路径 文件名主干 文件后缀 注意: 文件标识被称为文件名,但此时的文件名包括以上三部分内容, 而不仅是文件名主干。 文件名主干的命名规则遵循标识符的命名规则。后缀用来表 示文件的性质,一般不超过3个字母. 如:.doc (Word 生成的文件),.txt (文本文件),.dat (数据文件)
6
§10.1 C文件的有关概念 10.1.3 文件的分类 根据数据的组织形式,数据文件可分为ASCII 文件和二进制文件。
ASCII文件(文本文件):每一个字节放一个ASCII代码 二进制文件:把内存中的数据按其在内存中的存储形 式原样输出到磁盘上存放. 例:整数10000在内存中的存储形式以及分别按ASCII 码形式和二进制形式输出如下图所示:
7
§10.1 C文件的有关概念 10.1.3 文件的分类 ASCII文件和二进制文件的比较: ASCII文件便于对字符进行逐个处理,也便于输出
字符。但一般占存储空间较多,而且要花费转换时 间。 二进制文件可以节省外存空间和转换时间,但一个 字节并不对应一个字符,不能直接输出字符形式。 一般中间结果数据需要暂时保存在外存上,以后又 需要输入内存的,常用二进制文件保存。
8
§10.1 C文件的有关概念 10.1.4 文件缓冲区 ANSI C标准采用“缓冲文件系统”处理文件.
缓冲文件系统:系统自动地在内存区为每一个正 在使用的文件开辟一个缓冲区。 从内存向磁盘输出数据必须先送到内存中的缓冲 区,装满缓冲区后才一起送到磁盘去。 文件 程序 数据区 输出文件缓冲区 输入文件缓冲区
9
§10.1 C文件的有关概念 10.1.5 文件指针 不同的C编译系统的FILE类型包含的内容不完全相同,但大同小
异。 Turbo C在stdio.h文件中有以下的文件类型声明: typedef struct { shortlevel; /*缓冲区“满”或“空”的程度*/ unsignedflags; /*文件状态标志*/ charfd; /*文件描述符*/ unsignedcharhold; /*如无缓冲区不读取字符*/ shortbsize; /*缓冲区的大小*/ unsignedchar*buffer;/*数据缓冲区的位置*/ unsignedar*curp;/*指针,当前的指向*/ unsignedistemp;/*临时文件,指示器*/ shorttoken;/*用于有效性检查*/}FILE; 在缓冲文件系统中,每个被使用的文件都要在内存中开辟一 FILE类型的区,存放文件的有关信息.
10
§10.1 C文件的有关概念 10.1.5 文件指针 FILE类型的数组: 文件型指针变量:
FILE f[5];定义了一个结构体数组f,它有5个元素, 可以用来存放5个文件的信息。 文件型指针变量: FILE *fp;fp是一个指向FILE类型结构体的 指针变量。可以使fp指向某一个文件的结构体变量,从 而通过该结构体变量中的文件信息能够访问该文件。如果 有n个文件,一般应设n个指针变量,使它们分别指向n 个文件,以实现对文件的访问。
11
§10.1 C文件的有关概念 10.1.5 文件指针 在标准输入输出库中,系统定义了三个FILE型的指针变量:
stdin (标准输入文件指针) 。指向在内存中与键盘相应的文件 信息区,因此,用它进行输入就蕴含了从键盘输入。 2.stdout (标准输出文件指针) 。指向在内存中与显示器屏幕相应 的文件信息区,因此,用它进行输出就蕴含了输出到显示器屏幕。 3.stderr (标准错误文件指针),用来输出出错的信息,它也指向在 内存中与显示器屏幕相应的文件信息区,因此,在程序运行时的出 错的信息就输出到显示器屏幕。
12
§10.1 C文件的有关概念 10.1.6 文件的位置指针 位置指针用来指示当前的读写位置。
一般情况下,在对字符文件进行顺序读写时,文件的位置指针指向 文件开头,这时如果对文件进行读的操作,就读第一个字符,然后 文件的位置指针顺序向后移一个位置,在下一次执行读的操作时, 就将指针指向的第二个字符读入。依此类推,直到遇文件尾. ↑ ↑ ↑ 文件头 读写当前位置 文件尾 有时希望在一个文件的原有数据之后再添加新的数据,应该把文件位置指针移到文件尾,然后再接着写入新的数据,这就是文件的追加。
13
§10.2 文件的打开与关闭 10.2.1文件的打开(fopen函数) 函数调用: FILE *fp;
fp=fopen(文件名,使用文件方式); ①需要打开的文件名,也就是准备访问的文件的名字; ②使用文件的方式(“读”还是“写”等); ③让哪一个指针变量指向被打开的文件。
14
§10.2 文件的打开与关闭 10.2.1 文件的打开(fopen函数)
文件使用方式 含 义 “r” (只读)为输入打开一个文本文件 “w” (只写)为输出打开一个文本文件 “a” (追加)向文本文件尾增加数据 “rb” (只读)为输入打开一个二进制文件 “wb” (只写)为输出打开一个二进制文件 "ab“ (追加)向二进制文件尾增加数据 "r+“ (读写)为读/写打开一个文本文件 "w+” (读写)为读/写建立一个新的文本文件 "a+” (读写)为读/写打开一个文本文件 "rb+“ (读写)为读/写打开一个二进制文件 “wb+“ (读写)为读/写建立一个新的二进制文件 “ab+” (读写)为读/写打开一个二进制文件
15
§10.2 文件的打开与关闭 10.2.2 文件的关闭(fclose函数)
函数调用: fclose(文件指针); 函数功能: 使文件指针变量不指向该文件,也就是文件指针变 量与文件“脱钩”,此后不能再通过该指针对原来与 其相联系的文件进行读写操作 返回值: 关闭成功返回值为0;否则返回EOF(-1)
16
§10.3 文件的顺序读写 10.3.1 向文件读写一个字符 1.用fputc函数向文件写入一个字符. 调用形式:
§10.3 文件的顺序读写 向文件读写一个字符 1.用fputc函数向文件写入一个字符. 调用形式: fputc ( ch,fp ) ; 函数功能: 将字符(ch的值)输出到fp所指向的文件中去。 返回值: 如果输出成功,则返回值就是输出的字符; 如果输出失败,则返回一个EOF.
17
§10.3 文件的顺序读写 10.3.1 向文件读写一个字符 2.fgetc函数从文件读入一个字符.调用形式: ch=fgetc(fp);
§10.3 文件的顺序读写 向文件读写一个字符 2.fgetc函数从文件读入一个字符.调用形式: ch=fgetc(fp); 函数功能: fgetc函数带回一个字符,赋给ch。 返回值: 如果在执行fgetc函数读字符时遇到文件结束 符,函数返回一个文件结束标志EOF(即-1)。
18
§13.4 文件的读写(续) 3. 读写字符举例 fputc和fgetc函数使用举例: 例13.1从键盘输入一些字符,逐个把它们送到
例10.1 从键盘输入一些字符,逐个把它们送到磁盘上去,直到输入一个 “#”为止。 #include <stdlib.h> #include <stdio.h> void main(void) { FILE *fp; char ch,filename[10]; scanf("%s",filename); if((fp=fopen(filename,"w"))==NULL) { printf("cannot open file\n"); exit(0); /*终止程序*/} ch=getchar( ); /*接收执行scanf语句时最后输入的回车符 */ ch=getchar( ); /* 接收输入的第一个字符 */ while(ch!='#'{ fputc(ch,fp);putchar(ch); ch=getchar(); } fclose(fp); } §13.4 文件的读写(续) fputc和fgetc函数使用举例: 例13.1从键盘输入一些字符,逐个把它们送到 磁盘上去,直到输入一个“#”为止。 运行情况如下: file1.c (输入磁盘文件名) computer and c#(输入一个字符串) computer and c (输出一个字符串)
19
§13.4 文件的读写(续) fputc和fgetc函数使用举例: 例13.2将一个磁盘文件中的信息复制到另一个磁 盘文件中 。
例10.2 将一个磁盘文件中的信息复制到另一个磁盘文件中。 #include <stdlib.h> #include <stdio.h> main( ) {FILE *in,*out; char ch,infile[10],outfile[10]; printf("Enter the infile name:\n"); scanf("%s",infile); printf("Enter the outfile name:\n"); scanf("%s",outfile); if((in=fopen(infile,"r"))==NULL) { printf("cannot open infile\n"); exit(0);} if((out=fopen(outfile,"w"))==NULL) { printf("cannot open outfile\n"); while(!feof(in))fputc(fgetc(in),out); fclose(in); fclose(out);} §13.4 文件的读写(续) fputc和fgetc函数使用举例: 例13.2将一个磁盘文件中的信息复制到另一个磁 盘文件中 。 运行情况如下: Enter the infile name file1.dat(输入原有磁盘文件名 Enter the outfile name: file2.dat (输入新复制的磁盘文件名) 程序运行结果是将file1.dat文件中的内容复制到 file2.dat中去。
20
§10.3 文件的顺序读写 10.3.2 向文件读写一个字符串 fgets函数 函数原形
§10.3 文件的顺序读写 向文件读写一个字符串 fgets函数 函数原形 char *fgets(char *str, int n, FILE *fp); 函数功能: 从指定的文件读入一个字符. 返回值: 若执行fgets函数成功,则返回值为str数 组首元素的地址 如果一开始就遇到文件尾或读数据出错,则返回 NULL。
21
§10.3 文件的顺序读写 10.3.2 向文件读写一个字符串 fputs函数 函数原形
§10.3 文件的顺序读写 向文件读写一个字符串 fputs函数 函数原形 int fputs(const str, FILE *fp); 函数功能: 用fputs函数可以向指定的文件输出一个字符串.
22
§13.4 文件的读写(续) fputc和fgetc函数使用举例: 例13.2将一个磁盘文件中的信息复制到另一个磁 盘文件中 。
例10.3从键盘读入若干个字符串,对它们按字母顺序排序, 后把它们送到谚磁盘文件中保存. #include <stdio.h> #include <stdlib.h> #include <string.h> void main() { FILE *fp; char str[3][10],temp[10]; int i,j,k,n=3; printf("Enter strings:\n"); for(i=0;i<n;i++) gets(str[i]); for(i=0;i<n-1;i++) {k=i; for(j=i+1;j<n;j++) if(strcmp(str[k],str[j])>0) k=j; fputc和fgetc函数使用举例: 例13.2将一个磁盘文件中的信息复制到另一个磁 盘文件中 。
23
§13.4 文件的读写(续) fputc和fgetc函数使用举例: 例13.2将一个磁盘文件中的信息复制到另一个磁 盘文件中 。
if(k!=i) {strcpy(temp,str[i]); strcpy(str[k], strcpy(str[i],str[k]); temp);} } if((fp=fopen("D:\\CC\\temp\\string.dat","w"))==NULL) { printf("can't open file!\n"); exit(0); printf("\nThe new sequence:\n"); for(i=0;i<n;i++) {fputs(str[i],fp);fputs("\n",fp); printf("%s\n",str[i]); } fputc和fgetc函数使用举例: 例13.2将一个磁盘文件中的信息复制到另一个磁 盘文件中 。 运行情况: Enter strings: China↙ Canada↙ India↙ The new sequence: Canada China India
24
§10.3 文件的顺序读写 10.3.3 向文件进行格式化读写 函数调用: 函数功能: 例:
§10.3 文件的顺序读写 向文件进行格式化读写 函数调用: fprintf ( 文件指针,格式字符串,输出表列); fscanf ( 文件指针,格式字符串,输入表列); 函数功能: 从磁盘文件中读入或输出字符。 例: fprintf(fp,”%d,%6.2f”,i,t); Fscanf (fp,”%d,%f”,&i,&t); 注意: 用fprintf和fscanf函数对磁盘文件读写,使用方便,容易理解, 但由于在输入时要将ASCII码转换为二进制形式,在输出时又要 将二进制形式转换成字符,花费时间比较多。因此,在内存与磁 盘频繁交换数据的情况下,最好不用fprintf和fscanf函数,而 用fread和fwrite函数。
25
§10.3 文件的顺序读写 10.3.4向文件读写一组数据 数据块读写函数(fread()和fwrite()) 函数调用:
§10.3 文件的顺序读写 向文件读写一组数据 数据块读写函数(fread()和fwrite()) 函数调用: fread (buffer,size,count,fp); fwrite(buffer,size,count,fp); 参数说明: buffer:是一个指针。 对fread 来说,它是读入数据的存放地址。 对fwrite来说,是要输出数据的地址(均指起始地址)。 size: 要读写的字节数。 count: 要进行读写多少个size字节的数据项。 fp: 文件型指针。
26
§10.3 文件的顺序读写 10.3.4 向文件读写一组数据 使用举例: 若文件以二进制形式打开: fread(f,4,2,fp);
§10.3 文件的顺序读写 向文件读写一组数据 使用举例: 若文件以二进制形式打开: fread(f,4,2,fp); 此函数从fp所指向的文件中读入2个4个字节的数 据,存储到数组f中。
27
§10.3 文件的顺序读写 10.3.4 向文件读写一组数据 使用举例: 若有如下结构类型: struct student_type
§10.3 文件的顺序读写 向文件读写一组数据 使用举例: 若有如下结构类型: struct student_type {char name[10]; int num; int age; char addr[30];}stud[40]; 可以用fread和fwrite来进行数据的操作: for(i=0;i<40;i++) fread(&stud[i],sizeof(struct student-type),1,fp); for(i=0;i<40,i++) fwrite(&stud[i],sizeof(struct student-type),1,fp);
28
§10.3 文件的顺序读写 10.3.4 向文件读写一组数据 使用举例: 例10.4从键盘输入4个学生的有关数据,然后把它们转存
§10.3 文件的顺序读写 向文件读写一组数据 使用举例: 例10.4从键盘输入4个学生的有关数据,然后把它们转存 到磁盘文件上去。 #include <stdio.h> #define SIZE 4 struct student_type { char name[10]; int num; int age; char addr[15]; }stud[SIZE]; /*定义结构*/
29
§13.4 文件的读写(续) void save( ) {FILE *fp; int i;
if((fp=fopen("stu-list","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); } /*关闭文件*/ void main() {int i; for(i=0;i<SIZE;i++)/*从键盘读入学生信息*/ scanf("%s%d%d%s",stud[i].name,&stud[i].num, &stud[i].age,stud[i].addr); save( );}/*调用save()保存学生信息*/ 运行情况如下: 输入4个学生的姓名、学号、年龄和地址: Zhang 1001 19 room-101 Fun 1002 20 room-102 Tan 1003 21 room-103 Ling 1004 21 room-104
30
§13.4 文件的读写(续) #include <stdio.h> #define SIZE 4
struct student_type { char name[10]; int num; int age; char addr[15]; }stud[SIZE]; void main( ) { int i; FILE*fp; fp=fopen("stu-list","rb"); 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);} §13.4 文件的读写(续) 验证在磁盘文件“stu-list”中是否已存在此数据, 用以下程序从“stu-list”文件中读入数据,然后在 屏幕上输出。 屏幕上显示出以下信息: Zhang 1001 19 room-101 Fun 1002 20 room-102 Tan 1003 21 room-103 Ling 1004 21 room-104
31
§10.3 文件的顺序读写 10.3.4 向文件读写一组数据 如果已有的数据已经以二进制形式存储在一个磁盘文件
§10.3 文件的顺序读写 向文件读写一组数据 如果已有的数据已经以二进制形式存储在一个磁盘文件 “stu-dat”中,要求从其中读入数据并输出到 “stu-list”文件中,可以编写一个load函数, 从磁盘文件中读二进制数据。 void load( ) {FILE *fp;int i; if((fp=fopen("stu-dat","rb"))==NULL) { printf("cannot open infile\n"); return;} for(i=0;i<SIZE;i++) if(fread(&stud[i],sizeof(struct student_type),1,fp)!=1) {if(feof(fp)) {fclose(fp); return;} printf("file read error\n");} fclose (fp); }
32
§10.4 文件的随机读写 10.4.1 文件位置指针的定位 顺序读写和随机读写 顺序读写: 位置指针按字节位置顺序移动。 随机读写:
读写完上一个字符(字节)后,并不一定要读写其后续 的字符(字节),而可以读些文件中任意位置上所需要 的字符(字节)。 文件位置指针的定位 C语言提供以下有关函数使位置指针指向指定的位置: (1)rewind函数 函数功能: 是使位置指针重新返回文件的开头,此函数没有返回值。
33
#include<stdio.h> main() { FILE *fp1,*fp2;
例10.5 有一个磁盘文件,第一次将它的内容显示在屏幕上, 第二次把它复制到另一文件上。 #include<stdio.h> main() { FILE *fp1,*fp2; fp1=fopen("file1.c","r"); fp2=fopen("file2.c","w"); while(!feof(fp1)) putchar(getc(fp1)); rewind(fp1); while(!feof(fp1)) putc(getc(fp1),fp2); fclose(fp1);fclose(fp2); } rewind函数 函数作用: 使位置指针重新返回文件的开头,无返回值。 应用举例: 例13.4有一个磁盘文件,第一次将它的内容显示在屏幕 上,第二次把它复制到另一文件上。
34
10.4.1 文件位置指针的定位 (2)fseek函数 函数功能: 改变文件的位置指针 函数调用形式:
fseek(文件类型指针,位移量,起始点) 起始点:文件开头 SEEK_SET 0 文件当前位置 SEEK_CUR 1 文件末尾 SEEK_END 2 位移量:以起始点为基点,向前移动的字节数。一般 要求为long型
35
10.4.1 文件位置指针的定位 fseek函数应用举例: fseek(fp,100L,0); 将位置指针移到离文件头100个字节处
将位置指针移到离当前位置50个字节处 fseek(fp,50L, 2); 将位置指针从文件末尾处向后退10个字节
36
10.4.1 文件位置指针的定位 (3)ftell函数 函数功能: 得到流式文件中的当前位置,用相对于文件开头的位 移量来表示。 返回值:
返回当前位置,出错时返回-1L。 应用举例: i = ftell(fp); if(i==-1L) printf(“error\n”);
37
10.4.2 随机读写 rewind函数 函数作用: 使位置指针重新返回文件的开头,无返回值。
随机读写 例10.6在磁盘文件上存有10个学生的数据。要求将第1、3、 5、7、9个学生数据输入计算机,并在屏幕上显示出来。 #include <stdlib.h> #include<stdio.h> struct student_type { char name[10]; int num; int age; char sex; }stud[10]; rewind函数 函数作用: 使位置指针重新返回文件的开头,无返回值。 应用举例: 例13.4有一个磁盘文件,第一次将它的内容显示在屏幕 上,第二次把它复制到另一文件上。
38
使位置指针重新返回文件的开头,无返回值。 应用举例:
void main() { int i; FILE *fp; if((fp=fopen("stud_dat","rb"))==NULL) {printf("can not open file\n"); exit(0); } for(i=0;i<10;i+=2) { fseek(fp,i*sizeof(struct student_type),0); fread(&stud[i], sizeof(struct student_type) ,1,fp); printf("%s %d %d %c\n",stud[i].name,stud[i]. num,stud[i].age,stud[i].sex); fclose(fp); rewind函数 函数作用: 使位置指针重新返回文件的开头,无返回值。 应用举例: 例13.4有一个磁盘文件,第一次将它的内容显示在屏幕 上,第二次把它复制到另一文件上。
39
§10.5 文件读写的出错检测 (1)ferror函数 调用形式: ferror(fp); 返回值:
返回0,表示未出错;返回非0,表示出错。 在调用一个输入输出函数后立即检查ferror函数的值, 否则信息会丢失。在执行fopen函数时,ferror函数 的初始值自动置为0。
40
§10.5 文件读写的出错检测 (2)clearerr函数 调用形式: clearerr(fp); 函数作用:
使文件错误标志和文件结束标志置为0。 只要出现错误标志,就一直保留,直到对同一文件 调用clearerr函数或rewind函数,或任何其他一个输 入输出函数。
Similar presentations