Successfully reported this slideshow.
We use your LinkedIn profile and activity data to personalize ads and to show you more relevant ads. You can change your ad preferences anytime.

C语言

1,187 views

Published on

  • Be the first to comment

  • Be the first to like this

C语言

  1. 1. 第十章 文件 § 10.1 C 文件概述 文件:存储在外部介质上数据的集合 , 是操作系 统数据管理的单位 文件分类 使用数据文件的目的 1 、数据文件的改动不引起程序的改动——程序与数据分离 按文件的逻辑结构: 2 、不同程序可以访问同一数据文件中的数据——数据共享 3 、能长期保存程序运行的中间数据或结果数据  记录文件:由具有一定结构的记录组成(定长和不定长)  流式文件:由一个个字符(字节)数据顺序组成 按存储介质:  普通文件:存储介质文件(磁盘、磁带等)  设备文件:非存储介质(键盘、显示器、打印机等) 按数据的组织形式:  文本文件: ASCII 文件,每个字节存放一个字符的 ASCII 码  二进制文件:数据按其在内存中的存储形式原样存放
  2. 2. 文本文件特点 : 存储量大、速度慢、便于对字符操作 如 int 型数 10000 ASCII 形式 0011000100110000001100000011000000110000 0010011100010000 0010011100010000 内存存储形式 二进制形式 二进制文件特点 : 存储量小、速度快、便于存放中间结果
  3. 3. 文件处理方法 缓冲文件系统:高级文件系统,系统自动为正在使用 的文件开辟内存缓冲区 非缓冲文件系统:低级文件系统,由用户在程序中为 每个文件设定缓冲区 程序 输入文件缓冲区 缓冲文件系统: 指令区 磁盘文件 程序数据区 非缓冲文件系统: 用户数据区 a 磁盘 输出文件缓冲区 缓冲区
  4. 4. § 10.2 文件类型指针 文件结构体 FILE  缓冲文件系统为每个正使用的文件在内存开辟文件 信息区 文件信息用系统定义的名为 FILE 的结构体描述 FILE 定义在 stdio.h 中 typedef struct { int _fd; // 文件号 int _cleft; // 缓冲区中剩下的字符数 int _mode; // 文件操作方式 char *_next; // 文件当前读写位置 char *_buff; // 文件缓冲区位置 }FILE;
  5. 5. 文件类型指针 指针变量说明: FILE *fp; 用法:  文件打开时,系统自动建立文件结构体,并把指向它的指针 返回来,程序通过这个指针获得文件信息 , 访问文件  文件关闭后,它的文件结构体被释放 文件名 文件使用 C 程序 方式 操作系统 文件类型指针 磁盘
  6. 6. § 10.3 文件的打开与关闭 C 文件操作用库函数实现 , 包含在 stdio.h 文件使用方式 含义 例 文件打开与测试 文件使用方式 *fp; “r/rb” ( 只读 ) FILE : 为输入打开一个文本 / 二进制文件 --> 关闭 打开文件 --> 文件读 / 写 文件 “w/wb” ( 只写 ) fp=fopen(“aa.c”,“w”); 为输出打开或建立一个文本 / 二进制文件 “a/ab” ( 追加 ) if(fp==NULL) / 二进制文件尾追加数据 系统自动打开和关闭三个标准文件: 向文本 例 FILE printf(“File open error!n”); *fp; 例 FILE { “r+/rb+” ( 读写 ) *fp; 为读 / 写打开一个文本 / 二进制文件 标准输入 ------ 键盘 char *filename=“c:fengyibkctest.dat” exit(0); stdin fp= fopen (“c:fengyibkctest.dat”,”r”); “w+/wb+” ( 读写 ) fopen(filename,”r”); fp= 标准输出 ------ 显示器 写建立一个文本 / 二进制文件 } 为读 / stdout “a+/ab+” ( 读写 ) 标准出错输出 ----- 写打开或建立一个文本 / 二进制文件 为读 / 显示器 stderr 使用文件方式 打开文件 fopen 函数原型: FILE *fopen(char *name,char *mode) 功能:按指定方式打开文件 要打开的文件名 返值:正常打开,为指向文件结构体的指针;打 开失败,为 NULL
  7. 7. 文件关闭 fclose 作用 : 使文件指针变量与文件“ 脱钩”,释放文件结构 体和文件指针 函数原型: int fclose(FILE *fp) 功能:关闭 fp 指向的文件 返值:正常关闭为 0; 出错时 , 非 0 文件打开时返回的文件类型指针 缓冲文件系统: 不关闭文件可能会丢失数据 输入文件缓冲区 磁盘文件 程序数据区 a 输出文件缓冲区 fclose
  8. 8. § 10.4 文件的读写 字符 I/O:fputc 与 fgetc fputc  函数原型: int fputc(int c, FILE *fp)  功能:把一字节代码 c 写入 fp 指向的文件中  返值:正常,返回 c; 出错,为 EOF fgetc  函数原型: int fgetc(FILE *fp)  功能:从 fp 指向的文件中读取一字节代码  返值:正常,返回读到的代码值 ; 读到文件尾或出错,为 文件 I/O 与终端EOF I/O #define putc(ch,fp) fputc(ch,fp) #define getc(fp) fgetc(fp) #define putchar( c ) fputc(c,stdout) #define getchar( ) fgetc(stdin)
  9. 9. 例 #include <stdio.h> 从键盘输入字符,逐个 #include <stdio.h> 存到磁盘文件中,直到 main() main() 输入‘ #“ 为止 {{ FILE *fp; *out; FILE *in, 判断二进制文件是否结束 char ch,infile[10],outfile[10]; char ch,*filename=“out.txt”; #include <stdio.h> while(!feof(fp)) scanf(quot;%squot;,infile); if((fp=fopen(filename,quot;wquot;))==NULL) Ch12_1.c main() { printf(quot;cannot open c=fgetc(fp); {scanf(quot;%squot;,outfile); filenquot;); { FILE *fp; …….. if ((in = fopen(infile, quot;rquot;))== NULL) exit(0); 例 读文本文件内容, char ch,*filename=“out.txt”; 并显示 {} printf(quot;Cannot open infile.nquot;); } if((fp=fopen(filename,”rquot;))==NULL) exit(0); printf(quot;Please inputopen filenquot;); { printf(quot;cannot string:quot;); 例 文件拷贝 } ch=getchar(); feof exit(0); if ((out = fopen(outfile, quot;wquot;))== NULL) while(ch!='#') }  函数原型: int feof(FILE *fp)open outfile.nquot;); { printf(quot;Cannot Ch12_2.c { while((ch=fgetc(fp))!=EOF) fputc(ch,fp);  功能:判断文件是否结束 exit(0); putchar(ch); } ch=getchar();  返值:文件结束,返回真(非 0 );文件未结束,返回 0 fclose(fp); 判断文本文件是否结束 while (!feof(in)) }} fputc(fgetc(in), out); fclose(fp); } fclose(in); fclose(out); }
  10. 10. 数据块 I/O:fread 与 fwrite 函数原型: size_t fread(void *buffer,size_t size, size_t count,FILE *fp) size_t fwrite(void *buffer,size_t size, size_t count,FILE *fp) 功能:读 / 写数据块 返值:成功,返回读 / 写的块数;出错或文件尾,返回 0 说明:  typedef unsigned size_t;  buffer: 指向要输入 / 输出数据块的首地址的指针  size: 每个要读 / 写的数据块的大小(字节数)  count: 要读 / 写的数据块的个数  fp: 要读 / 写的文件指针  fread 与 fwrite 一般用于二进制文件的输入 / 输出
  11. 11. 例 float f[2]; FILE *fp; fp=fopen(“aa.dat”,“rb”); for(i=0;i<2;i++) fread(f,4,2,fp); fread(&f[i],4,1,fp); 例 struct student { int num; char name[20]; char sex; int age; float score[3]; }stud[10]; for(i=0;i<10;i++) fread(&stud[i],sizeof(struct student),1,fp);
  12. 12. Ch12_3.c 例 从键盘输入 4 个学生数据,把他们转存到磁盘文件中去 #include <stdio.h> void save() void display() #define SIZE 2 { {FILE *fp; FILE *fp; struct student_type int i; i; int { char name[10]; if((fp=fopen(quot;d:fengyiexestu_datquot;,quot;wbquot;))==NULL) if((fp=fopen(quot;d:fengyiexestu_datquot;,quot;rbquot;))==NULL) int num; { { printf(quot;cannot open filenquot;); printf(quot;cannot open filenquot;); int age; return; return; char addr[15]; }} }stud[SIZE]; for(i=0;i<SIZE;i++) for(i=0;i<SIZE;i++) main() if(fwrite(&stud[i],sizeof(struct student_type),1,fp)!=1) { fread(&stud[i],sizeof(struct student_type),1,fp); { printf(quot;file write errornquot;); printf(quot;%-10s %4d %4d %-15snquot;,stud[i].name, int i; fclose(fp); stud[i].num,stud[i].age,stud[i].addr); for(i=0;i<SIZE;i++) } } fclose(fp); scanf(quot;%s%d%d%squot;,stud[i].name,&stud[i].num, } &stud[i].age,stud[i].addr); save(); display(); }
  13. 13. 格式化 I/O:fprintf 与 fscanf 函数原型: #include <stdio.h> main() int fprintf(FILE *fp,const char *format[,argument,…]) int fscanf(FILE s[80],c[80]; { char *fp,const char *format[,address,…]) int a,b; 功能:按格式对文件进行 I/O 操作 FILE *fp; 返值:成功 , 返回 I/O 的个数 ; 出错或文件尾 , 返回 if((fp=fopen(quot;testquot;,quot;wquot;))==NULL) EOF { puts(quot;can't open filequot;); exit() ; } 例 fprintf(fp,“%d,%6.2f”,i,t); // 将 i 和 t 按 %d,%6.2f 格式输出到 fp 文件 fscanf(stdin,quot;%s%dquot;,s,&a);/*read from keaboard*/ fscanf(fp,“%d,%f”,&i,&t); // 若文件中有 3,4.5 , 则将 3 送入 i, 4.5 送入 t fprintf(fp,quot;%s %dquot;,s,a);/*write to file*/ 例 从键盘按格式输入数据存到磁盘文件中去 fclose(fp); if((fp=fopen(quot;testquot;,quot;rquot;))==NULL) { puts(quot;can't open filequot;); exit(); } Ch12_70.c fscanf(fp,quot;%s%dquot;,c,&b);/*read from file*/ fprintf(stdout,quot;%s %dquot;,c,b);/*print to screen*/ fclose(fp); }
  14. 14. 字符串 I/O: fgets 与 fputs #include<stdio.h> 函数原型: char *fgets(char *s,int n,FILE *fp) main() int fputs(char *s,FILE *fp) { FILE *fp; 功能:从 fp 指向的文件读 / 写一个字符串char string[81]; if((fp=fopen(quot;file.txtquot;,quot;wquot;))==NULL) 返值: fputs 把 s 指向的字符串写入 fp 指向的文件 fgets 从 正常时返回读取字符串的首地址;出错或文件尾,返回 , }  fgets fp 所指文件读 n- 1 个字符送入 s 指向的内存区 { printf(quot;cann't open filequot;);exit(0); 并在最后加一个‘ 0’ while(strlen(gets(string))>0) NULL ( 若读入 正常时返回写入的最后一个字符;出错为 EOF )即结束 )  fputs n- 1 个字符前遇换行符或文件尾( EOF { fputs(string,fp); fputs(quot;nquot;,fp); 例 从键盘读入字符串存入文件,再从文件读回显示 } fclose(fp); Ch12_400.c if((fp=fopen(quot;file.txtquot;,quot;rquot;))==NULL) { printf(quot;cann't open filequot;);exit(0); } while(fgets(string,81,fp)!=NULL) fputs(string,stdout); fclose(fp); }
  15. 15. § 10.5 文件的定位 几个概念 文件位置指针 ----- 指向当前读写位置的指针 读写方式 #include <stdio.h>  顺序读写:位置指针按字节位置顺序移动,叫 ~ main()  随机读写:位置指针按需要移动到任意位置,叫 ~ { FILE *fp1,*fp2; rewind 函数 fp1=fopen(quot;d:fengyibkcch12_4.cquot;,quot;rquot;); fp2=fopen(quot;d:fengyibkcch12_41.cquot;,quot;wquot;); 函数原型: void rewind(FILE *fp) while(!feof(fp1)) putchar(getc(fp1)); 功能:重置文件位置指针到文件开头 rewind(fp1); 返值:无 while(!feof(fp1)) putc(getc(fp1),fp2); fclose(fp1); 例 对一个磁盘文件进行显示和复制两次操作 fclose(fp2); } Ch12_4.c
  16. 16. main() fseek 函数 int i; { #includequot;stdio.hquot; FILEmain() *fp; 函数原型: int fseek(FILE *fp,long offset,int whence) { FILE *fp; if((fp=fopen(quot;studatquot;,quot;rbquot;))==NULL) 功能:改变文件位置指针的位置 char filename[80]; { printf(quot;can't open filenquot;);exit(0); } 返值:成功,返回 0 ;失败,返回非 0 值 long length; for(i=0;i<3;i+=2) 位移量(以起始点为基点 , 移动的字节数 gets(filename); 文件指针 起始点 { fseek(fp,i*sizeof(struct student_type),0); ftell 函数 ) 例 fseek(fp,100L,0); fp=fopen(filename,quot;rbquot;); 文件开始 SEEK_SET 0 fread(&stud[i],sizeof(struct student_type),1,fp); fseek(fp,50L,1); *fp) 函数原型: long ftell(FILE >0 向后移动 文件当前位置 if(fp==NULL) fseek(fp,-10L,2);not found!nquot;);SEEK_CUR 1 printf(quot;%s %d %d %snquot;, <0 向前移动 文件末尾 printf(quot;file 功能:返回位置指针当前位置 ( 用相对文件开头的位 stud[i].name,stud[i].num,stud[i].age,stud[i].addr); 2 SEEK_END 移量表示}) else { fseek(fp,0L,SEEK_END); #include <stdio.h> 返值:成功,返回当前位置指针位置;失败,返 fclose(fp); length=ftell(fp); struct student_type 回 -1L } , 例 磁盘文件上有 3 个学生数据,要求读入第 %1d 3 int num; { 学生数据并显示 printf(quot;Length of File is 1 , bytesnquot;,length); fclose(fp); char name[10]; 例 求文件长度 (ch12_101.c)} int age; } Ch12_5.c char addr[15]; }stud[3];
  17. 17. § 10.6 出错的检测 ferror 函数 函数原型: int ferror(FILE *fp) 功能:测试文件是否出现错误 返值:未出错, 0 ;出错,非 0 说明  每次调用文件输入输出函数,均产生一个新的 ferror 函数值 ,所以应及时测试  fopen 打开文件时, ferror 函数初值自动置为 0
  18. 18. clearerr 函数 #include <stdio.h> 函数原型: void clearerr(FILE *fp) int main(void) 功能:使文件错误标志置为 0 { FILE *stream; 返值:无 stream = fopen(quot;DUMMY.FILquot;, quot;wquot;); 说明:出错后,错误标志一直保留,直到对同一 getc(stream); 文件调 clearerr(fp) 或 rewind 或任何其它一个输 if (ferror(stream)) 入输出函数{ printf(quot;Error reading from DUMMY.FILnquot;); clearerr(stream); 例 ferror() 与 clearerr() 举例 } if(!ferror(stream)) Ch12_010.c printf(quot;Error indicator cleared!quot;); fclose(stream); return 0; }

×