1 / 32

第 12 章 文 件

第 12 章 文 件. §12.1 概述. 1. 文件 信息的集合 , 如一段程序、一段数据、一副图等. 计算机操作系统以文件形式存储信息 , 文件是最小的管理单位 如 源文件名 .c 、文件名 .obj 、文件名 .exe. 本章讲的是程序在运行中数据文件的输入输出. 输入文件 存在磁盘上的数据文件 , 程序运行中将文件的数据读入 内存相应变量、数组的存储单元. 输出文件 程序运行中将变量、数组 的数据以文件形式存于磁盘. 简单例子 , 读入一个数组 , 求最大值. for(i=0;i<5;i++)

zorina
Download Presentation

第 12 章 文 件

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. 第12章文 件 §12.1概述 1.文件信息的集合,如一段程序、一段数据、一副图等 计算机操作系统以文件形式存储信息,文件是最小的管理单位 如 源文件名.c、文件名.obj、文件名.exe 本章讲的是程序在运行中数据文件的输入输出 输入文件存在磁盘上的数据文件,程序运行中将文件的数据读入 内存相应变量、数组的存储单元 输出文件程序运行中将变量、数组 的数据以文件形式存于磁盘

  2. 简单例子,读入一个数组,求最大值. for(i=0;i<5;i++) {for(j=0;j<5;j++) printf("%d ", a[i][j]); printf("\n");} printf("max=%d\n",maxvalue(25,a)); } void main() {int a[5][5],i,j; for(i=0;i<5;i++) for(j=0;j<5;j++) scanf("%d",&a[i][j]); #include "stdio.h" int maxvalue(n,p) int n,*p; {int i,t; t=*p; for(i=1;i<n;i++) if(t<*(p+i)) t=*(p+i); return(t); } void main() {int a[5][5],i,j; FILE *fp,*fp1; fp=fopen("file1.txt","r"); for(i=0;i<5;i++) for(j=0;j<5;j++) fscanf(fp,"%d",&a[i][j]); fclose(fp); fp1=fopen("file2.txt","w"); for(i=0;i<5;i++) {for(j=0;j<5;j++) fprintf(fp1,"%d ", a[i][j]); fprintf(fp1,"\n");} fprintf(fp1,"maxvlue=%d\n",maxvalue(25,a)); fclose(fp1); }

  3. 采取数据文件的好处 (1)原始数据以文件输入保证数据的正确性,减少重复输入数据操作 (2)以文件形式输出,便于打印、存档 (3)使用数据文件内存交换,小机算大题 2.C语言文件按字节流存储,形式有文本(ASCII码)和二进制数据 文本文件字符形式存储,一个字符占一个字节 二进制文件二进制数据直接存储,存储字节数由数据的类型确定 两者比较 文本文件能用编辑软件编辑,但运算慢,一般用于原始数据文件和结果输出文件 二进制文件运算快,但文件内容不能阅读,一般作为中间结果文件

  4. 程序 数据区 磁盘 文件缓冲区 内存 3.C语言对数据文件的处理方法 文件缓冲区开设途征 (1)系统自动开设,使用之前需声明,称之缓冲文件系统 (2)用户自己开设,以数组形式定义,称之非缓冲文件系统 注 第(1)符合ANSI C标准

  5. 4.文件类型指针 在缓冲文件系统文件缓冲区通过结构变量指针实现 格式FILE *指针变量 例 FILE *fp; 操作 定义FILE类型指针,用于指向文件缓冲区,fp又称文件柄

  6. FILE是由struct定义的类型,在stdio.h库文件中可以查到FILE是由struct定义的类型,在stdio.h库文件中可以查到 • typedef struct • { short level; /* 缓冲区使用量 */ • unsigned flags; /* 文件状态标志 */ • char fd; /* 文件描述符 */ • short bsize; /* 缓冲区大小 */ • unsigned char *buffer; /* 文件缓冲区的首地址 */ • unsigned char *curp; /* 指向文件缓冲区的工作指针 */ • unsigned char hold; /* 其他信息 */ • unsigned istemp; • short token; • } FILE; 每个文件具有FILE结构体和文件缓冲区 通过fp->cup指示文件缓冲区中数据存取的位置 fp->cup存取文件缓冲区数据系统自动定位

  7. 5.使用数据文件的步骤 (1)定义文件指针变量 (2)打开或建立数据文件 (3)读、写文件数据 (4)关闭数据文件 C语言对数据文件的操作通过一系列函数实现

  8. §12.2文件的打开和关闭 12.2.1 文件的打开 使用函数 FILE *fopen(char *filename,char *type); 如 FILE *p; p=fopen("file1.dat","r"); 其中 char *filename:数据文件名,包括路径,缺省路径为当前目录 可以字符串常量或字符串变量 指出打开数据文件的路径和文件名 例 "d:\\user\\file1.dat“ p=fopen(" d:\\user\\file1.dat ","r"); name p=fopen(name,"r"); name经定义 char name[]="file1.dat";

  9. char *type: 字符串,指出打开文件的方式 规定r : 打开 只读 r+: 打开 读写 w: 创建 只写 w+: 创建 读写 a : 打开 追加 a+: 打开 读写 当打开的文件为二进制文件则*type后加b,否则为文本文件 如 rb, a+b 操作 打开文件,返回文件柄。具体步骤为: 在磁盘找指定路径下的指定文件,若无指定路径则为当前目录 在内存中分配一个FILE类型结构体的单元 在内存分配文件缓冲区单元 为FILE结构体填入相应的信息 返回FILE结构体的地址

  10. 注(1)fopen调用成功返回文件柄(指针),失败返回NULL(即0),因而一般打开文件时采用判别注(1)fopen调用成功返回文件柄(指针),失败返回NULL(即0),因而一般打开文件时采用判别 if((fp=fopen("file1.dat","r"))==NULL) {printf("Cannot open this file\n");exit(0);} 其中exit(0)是库函数(stdlib.h),作用是关闭所有打开的文件,并终止程序执行。参数0程序正常结束,参数非0程序不正常结束。 (2)程序开始运行时,系统自动打开三个标准文件 标准输入 stdin 键盘 标准输出 stdout 显示屏 标准出错输出 stderr 显示屏 可以使用标准文件指针指定键盘、显示屏输入输出 如 fprintf(stdout,“%s”,a); 等价 printf(“%s”,a);

  11. 12.2.2文件的关闭 使用函数 int fclose(FILE *文件指针); 如 FILE *fp; fp=fopen("file1.dat","r"); …… fclose(fp); 操作 关闭文件,将文件缓冲区的数据写盘并释放文件缓冲区 函数返回值为0 正常关闭,其它值关闭错误 所以 if(fclose(fp)) {printf("Cannot close this file\n"); exit(0); } 注 文件使用后应及时关闭,以免数据丢失

  12. §12.3文件的读写 12.3.1fputc函数和fgetc函数 1、fputc函数 格式int fputc(char ch,FILE *fp) 其中 ch : 输出字符 *fp : 文件指针 操作 将一个字符输出到文件 函数返回 成功:返回ch,失败:返回-1(EOF) 如 FILE *p; char c; fp=fopen("file1.dat","w"); …… fputc(c,fp); 与putchar(c)比较,输出设备不同 putchar(c); 等价 fputc(c,stdout);

  13. 例 从键盘输入10个字符,写到文件f1.txt中 分析 建立文件->键盘输入->写入文件->关闭文件 #include "stdio.h" #include "stdlib.h" void main() {int i;char ch;FILE *fp; if((fp=fopen("f1.txt","w"))==0) {printf("file open error!\n"); exit(0); } for(i=0;i<10;i++) {ch=getchar(); fputc(ch,fp); } if(fclose(fp)) {printf("file open error!\n"); exit(0); } }

  14. 2、fgetc函数 格式int fgetc(FILE *fp) 其中 fp : 文件指针 操作 从文件读入一个字符, 函数返回 成功:返回所取字符 失败或遇到文件结束:返回-1(EOF) 如 FILE *p; char c; p=fopen("file1.dat","r"); …… fgetc(p); 与getchar(c)比较,输入设备不同 getchar(); 等价 fgetc(stdin);

  15. 例12-4 从键盘输入10个字符,写到文件f2.txt,再从文件读出屏幕输出 分析 建立文件->键盘输入->写入文件->关闭文件 ->打开文件->读文件->屏幕输出->关闭文件 #include "stdio.h" #include "stdlib.h" main() {int i;char ch;FILE *fp; if((fp=fopen("f2.txt","w"))==0) {printf("file open error!\n"); exit(0); } for(i=0;i<10;i++) {ch=getchar(); fputc(ch,fp); } if(fclose(fp)) {printf("file close error!\n"); exit(0); } if((fp=fopen("f2.txt","r"))==NULL) {printf("file open error!\n"); exit(0); } for(i=0;i<10;i++) {ch=fgetc(fp); putchar(ch); } if(fclose(fp)) {printf("file close error!\n"); exit(0); } }

  16. 注:文件打开时,指针指向文件缓冲区的首部注:文件打开时,指针指向文件缓冲区的首部 文件读写时,指向文件缓冲区的指针自动依次下移 即 *(fp->curp)=ch; fp->curp++; fputc(ch,fp) 等价 ch=*(fp->curp); fp->curp++; ch=fgtc(fp) 等价 不能对文件指针fp和文件缓冲区指针控制改变 fp++ fp->curp++ 不允许 文件结束符EOF(end of file)控制文件结束 EOF =-1

  17. 从键盘输入一行字符,写到文件f3.txt,再从文件读出屏幕输出 #include "stdio.h" #include "stdlib.h" main() {char ch;FILE *fp; if((fp=fopen("f3.txt","w"))==0) {printf("file open error!\n"); exit(0); } while((ch=getchar())!='\n') fputc(ch,fp); if(fclose(fp)) {printf("file close error!\n"); exit(0); } if((fp=fopen("f3.txt","r"))==NULL) {printf("file open error!\n"); exit(0); } ch=fgetc(fp); while(ch!=EOF) /*或while(ch!=-1)*/ { putchar(ch); ch=fgetc(fp); } if(fclose(fp)) {printf("file close error!\n"); exit(0); } }

  18. 3、feof 函数 格式int feof(FILE *fp) 其中 fp : 文件指针 操作 测试文件是否结束, 结束返回值非0,否则返回0 如 FILE *fp; char c; fp=fopen("a.txt","r"); while(!feof(fp)) {c=fgetc(fp); …… } 读出文件的所有字符 ch=fgetc(fp); while(ch!=EOF) { …… ch=fgetc(fp); } 注 与使用EOF区别 使用EOF: 先读数,后判别 feof 函数:先判别,后读数

  19. 例12-3 将磁盘文件a.txt的内容复制到文件b.txt #include "stdio.h" #include "stdlib.h" main() {FILE *fpa,*fpb; if((fpa=fopen("a.txt","r"))==NULL) {printf("can not open file a.txt!\n"); exit(0); } if((fpb=fopen(nameo,"w"))==NULL) {printf("can not open file b.txt!\n"); exit(0); } while(!feof(fpi)) fputc(fgetc(fpa),fpb); fclose(fpa); fclose(fpb); } 如用EOF ch=fgetc(fpa); while(ch!=EOF) {fputc(c,fpb); ch=fgetc(fpa); }

  20. 12.3.2fputs 函数和 fgets函数 • 1.函数fputs( ) • 格式 intfputs(char *s, FILE *fp); • 其中, s要写入的字符串,可以是字符数组名、字符指针和字符串常量 • fp文件指针 • 操作 向指定的文本文件写入一个字符串,结束符'\0'不写入文件 • 函数返回 执行成功,函数返回所写的最后一个字符 • 否则,函数返回0

  21. 2.函数fgets( ) • 格式 char *fgets(char *s, int n,FILE *fp); • 其中, s字符数组名或字符指针 • n:指定读入的字符个数 • fp:文件指针 • 操作 从文本文件中读取字符串 • 函数被调用时,最多读取n-1个字符,并将读入的字符串存入s所指向内存地址开始的n-1个连续的内存单元中。 • 当函数读取的字符达到指定的个数,或接收到换行符,或接收到文件结束标志EOF时,将在读取的字符后面自动添加一个'\0'字符;若有换行符,则将换行符保留(换行符在'\0'字符之前);若有EOF,则不保留 • 函数返回值 • 执行成功,返回读取的字符串; • 如果失败,则返回空指针,这时,s的内容不确定

  22. 例12-5将字符串"apple", "grape", "pear" 写入到磁盘文件f12-5.txt中,然后再从该文件中读出,显示到屏幕。 int main(void) { FILE *fp; int i; char a[ ][80]={"apple", "grape", "pear"}, strout[80]=""; if((fp=fopen("f12-5.txt","w"))==NULL) {printf("File open error!\n"); exit(0);} for(i=0;i<3;i++) fputs(a[i], fp); fclose(fp); if((fp=fopen("f12-5.txt","r"))==NULL) {printf("File open error!\n"); exit(0);} i=0; while(!feof(fp)) {if( fgets(strout, strlen(a[i++])+1,fp) != NULL) puts(strout); } fclose(fp); }

  23. 12.3.3fprintf 函数和 fscanf函数 fprintf函数与printf函数 fscanf函数与scanf函数 作用相仿,均为格式化读写数据 不同的是前者对文件,后者对显示屏、键盘操作 格式fprintf(文件指针,格式字符串,输出表列); fscanf(文件指针,格式字符串,输入表列); 例 fprintf(fp,"%d,%6.2f",i,t); 若 i=3,t=4.5 输到文件中 3, 4.50 例 fscanf(fp,"%d,%f",&i,&t); 从文件读入数据赋值于i,t变量

  24. 例12-2将学生的计算机等级考试成绩,包括学号,姓名和分数保存到数据文件f.txt中.例12-2将学生的计算机等级考试成绩,包括学号,姓名和分数保存到数据文件f.txt中. 301101 张文 91 301102 陈慧 85 301103 王卫东 76 301104 郑伟 69 301105 郭温涛 55 #include<stdio.h> #include<stdlib.h> struct stud {long num; char stname[20]; int score;}st; void main() {FILE *fp;int i=0; if((fp=fopen("f.txt","w"))==NULL) {printf("file open error!\n"); exit(0);} do{scanf("%ld%s%d",&st.num,st.stname,&st.score); if(st.num>0) {if(i>0)fprintf(fp,"\n"); fprintf(fp,"%ld %s %d",st.num,st.stname,st.score); i++;} }while(st.num>0); fclose(fp); }

  25. 例12-2将数据文件f.txt中保存的学生的计算机等级考试成绩(包括学号、姓名和分数) 读出并显示到屏幕中。 #include<stdio.h> #include<stdlib.h> struct stud {long num; char stname[20]; int score;}st; void main() {FILE *fp; if((fp=fopen("f.txt","r"))==NULL) {printf("file open error!\n"); exit(0); } while(!feof(fp)) {fscanf(fp,"%ld%s%d", &st.num,st.stname,&st.score); printf("%ld %s %d\n",st.num,st.stname,st.score); } fclose(fp); }

  26. §12.4 文本文件与二进制文件 1、 文本文件 文本文件字符形式(ASCII码)存储,一个字符占一个字节 文件的打开: FILE *fopen(char *filename,char *type); char *type:打开文本表示 规定r : 打开 只读 r+: 打开 读写 w: 创建 只写 w+: 创建 读写 a : 打开 追加 a+: 打开 读写 文件的读写: int fgetc(FILE *p) int fputc(char ch,FILE *p) fprintf(文件指针,格式字符串,输出表列); fscanf(文件指针,格式字符串,输入表列); char *fgets(char *s,int n, FILE *p) int fputs(char *s, FILE *p) int getc (FILE *p) int putc (char c,FILE *p)

  27. 2、二进制文件 二进制文件二进制数据直接存储,存储字节数由数据的类型确定 文件的打开: FILE *fopen(char *filename,char *type); char *type:打开文本表示 规定rb : 打开 只读 rb+: 打开 读写 wb: 创建 只写 wb+: 创建 读写 ab : 打开 追加 ab+: 打开 读写 文件的读写: int fread(void *buffer,int size,int count,FILE *fp); int fwrite(void *buffer,int size,int count,FILE *fp); int getw(FILE *p) int putw(int w,FILE *p)

  28. §12.5 顺序文件和随机文件 顺序文件 按顺序读写文件的数据 一般文本文件为顺序文件 文件缓冲区指针指针定位: 打开文件时,指针定位文件开头 rewind函数将指针移至文件开头 格式 rewind(文件指针); #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); }

  29. 随机文件 随机读写文件的数据 一般文本文件为二进制文件 文件缓冲区指针定位: 打开文件时,指针定位文件开头 fseek函数将指针随机定位 fread函数读文件 fwrite函数写文件

  30. §12.6文件程序设计 使用数据文件的步骤 (1)定义文件指针变量 (2)打开或建立数据文件 (3)读、写文件数据 (4)关闭数据文件 其中步骤(1)(2)(4)的写法基本一致,仅步骤(3)稍有区别。

  31. 读指定的文本文件,显示在屏幕上,如果有大写字母,则改成小写字母再输出,并统计行数。 分析:根据回车符统计文件的行数。文件名通过键盘读入。 #include "stdio.h" #include "stdlib.h" main() {int line=1;FILE *fp; char name[10],ch; gets(name); if((fp=fopen(name,"r"))==NULL) {printf("%s file open error!\n",name); exit(0);} while(!feof(fp)) {ch=fgetc(fp); if(ch>='A'&&ch<='Z')ch+='a'-'A'; putchar(ch); if(ch=='\n') line++; } fclose(fp); printf("line=%d\n",line); }

  32. 例 把文本文件中的若干整数进行排序。 分析:把文件所有数据读到一个数组上,然后对数组排序,最后再写回文件。由于文件中数据个数未知,数组大小定义按最大情况考虑。 #include "stdio.h" #include "stdlib.h" #define Max 1000 main() {int i,j,a[Max]; FILE *fp; char name[10]; gets(name); if((fp=fopen(name,"r"))==0) {printf("%s can't open!\n",name); exit(0);} for(i=0;!feof(fp);i++) fscanf(fp,"%d",&a[i]); fclose(fp); sort(a,i); if((fp=fopen(name,"w"))==0) {printf("%s can't creat!\n",name); exit(0);} for(j=0;j<i;j++) fprintf(fp,"%d ",a[j]); fclose(fp);} void sort(int a[10],int n) {int i,j,k,t; for(i=0;i<n-1;i++) { k=i; for(j=i+1;j<n;j++) if(a[j]<a[k]) k=j; t=a[k];a[k]=a[i];a[i]=t; }}

More Related