开关文件

25
概概 概概概概 概概概概 概概概概 第第第 第 第

Upload: lacey-conley

Post on 14-Mar-2016

43 views

Category:

Documents


3 download

DESCRIPTION

第七章 文 件. 概述. 开关文件. 读写文件. 文件定位. C 文件概述. 文件:存储在外部介质上数据的集合 , 是操作系统数据管理的单位. 文件分类 按文件的逻辑结构: 记录文件:由具有一定结构的记录组成(定长和不定长) 流式文件 :由一个个字符(字节)数据顺序组成 按存储介质: 普通文件:存储介质文件(磁盘、磁带等) 设备文件 :非存储介质(键盘、显示器、打印机等) 按数据的组织形式: 文本文件 : ASCII 文件,每个字节存放一个字符的 ASCII 码 二进制文件 :数据按其在内存中的存储形式原样存放. 使用数据文件的目的 - PowerPoint PPT Presentation

TRANSCRIPT

Page 1: 开关文件

概述开关文件读写文件文件定位

第七章 文 件

Page 2: 开关文件

文件:存储在外部介质上数据的集合 , 是操作系统数据管理的单位文件分类

按文件的逻辑结构:记录文件:由具有一定结构的记录组成(定长和不定长)流式文件:由一个个字符(字节)数据顺序组成

按存储介质:普通文件:存储介质文件(磁盘、磁带等)设备文件:非存储介质(键盘、显示器、打印机等)

按数据的组织形式:文本文件: ASCII 文件,每个字节存放一个字符的 ASCII 码二进制文件:数据按其在内存中的存储形式原样存放

C 文件概述

Page 3: 开关文件

使用数据文件的目的1 、数据文件的改动不引起程序的改动——程序与数据分离2 、不同程序可以访问同一数据文件中的数据——数据共享3 、能长期保存程序运行的中间数据或结果数据

Page 4: 开关文件

如 int 型数 10000

0010011100010000

内存存储形式 0010011100010000

二进制形式

0011000100110000001100000011000000110000

ASCII 形式

文本文件特点 :存储量大、速度慢、便于对字符操作

二进制文件特点 :存储量小、速度快、便于存放中间结果

如 int 型数 10000

0010011100010000

内存存储形式 0010011100010000

二进制形式

0011000100110000001100000011000000110000

ASCII 形式

文本文件特点 :存储量大、速度慢、便于对字符操作

Page 5: 开关文件

文件处理方法缓冲文件系统:高级文件系统,系统自动为正在使用的文件开辟内存缓冲区非缓冲文件系统:低级文件系统,由用户在程序中为每个文件设定缓冲区

磁盘文件

输出文件缓冲区

输入文件缓冲区程序数据区

a

缓冲文件系统:

缓冲区

指令区程序

用户数据区 磁盘非缓冲文件系统:

Page 6: 开关文件

文件类型指针文件结构体 FILE

缓冲文件系统为每个正使用的文件在内存开辟文件信息区文件信息用系统定义的名为 FILE 的结构体描述FILE 定义在 stdio.h 中

typedef struct{ int _fd; // 文件号 int _cleft; // 缓冲区中剩下的字符数 int _mode; // 文件操作方式 char *_next; // 文件当前读写位置 char *_buff; // 文件缓冲区位置}FILE;

Page 7: 开关文件

文件类型指针指针变量说明: FILE *fp;用法:

文件打开时,系统自动建立文件结构体,并把指向它的指针返回来,程序通过这个指针获得文件信息 , 访问文件文件关闭后,它的文件结构体被释放文件名

文件使用方式文件类型指针

C 程序 操作系统

磁盘

Page 8: 开关文件

文件的基本操作步骤文件的基本操作步骤 各步骤的含义…各步骤的含义… ..

指向文件的指针变量指向文件的指针变量在“在“ stdio.h” stdio.h” 中中 struct _iobufstruct _iobuf { char _FAR_ *_ptr;{ char _FAR_ *_ptr; int _cnt;int _cnt; char _FAR_ *_base;char _FAR_ *_base; char _flag;char _flag; char _file;char _file; };};typedef struct _iobuf FILE ; typedef struct _iobuf FILE ;

打开文件 读写 ( 创建 ) 文件 关闭文件

typedef structtypedef struct{ int _fd ; /* { int _fd ; /* 文件号 文件号 */*/ int _cleft ; /* int _cleft ; /* 缓冲区剩下的字符 缓冲区剩下的字符 */*/ int _mode ; /* int _mode ; /* 文件操作模式 文件操作模式 */*/ char *_nextc ; /* char *_nextc ; /* 下一个字符指针 下一个字符指针 */*/ char *_buff ; /*char *_buff ; /* 文件缓冲区指针 文件缓冲区指针 */*/ } } FILEFILE ;例如:例如: FILE *fp1, *fp2;FILE *fp1, *fp2;

Page 9: 开关文件

1. 1. 打开文件打开文件

FILE *fp ;FILE *fp ;fp=fopen( filename, mode); fp=fopen( filename, mode); filenamefilename 中可以带路径名。中可以带路径名。一般方法如下:一般方法如下: FILE *fp;FILE *fp; if ((fp=fopen(“c:\doc\exam.txt”if ((fp=fopen(“c:\doc\exam.txt” “,“, w”)) = = NULL) w”)) = = NULL) { { puts(“Cannot open the file\n”); puts(“Cannot open the file\n”); exit(1);exit(1); } }

开关文件开关文件

Page 10: 开关文件

Mode(Mode( 方式方式 )) 意 义意 义 “ “r” r” 读文本文件读文本文件 “ “w” w” 写生成文本文件写生成文本文件 “ “a” a” 向文本文件追加向文本文件追加 “ “rb” rb” 读打开二进制文件读打开二进制文件 “ “wb” wb” 写生成进制文件写生成进制文件 “ “ab” ab” 向二进制文件追加向二进制文件追加

打开方式( mode)

Page 11: 开关文件

Mode(Mode( 方式方式 ) ) 意 义意 义 “ “r+” r+” 读写文本文件读写文本文件 “ “w+” w+” 读写读写 (( 创建创建 )) 文本文件文本文件 “ “a+” a+” 向文本文件追加向文本文件追加 “ “rb+” rb+” ““ 读打开”二进制文件读打开”二进制文件 “ “wb+” wb+” 读写读写 (( 创建创建 )) 二进制文件二进制文件 “ “ab+” ab+” 向二进制文件读写向二进制文件读写 (( 追加追加 ))

打开方式( mode)

Page 12: 开关文件

2. 2. 关闭文件关闭文件 一般方法如下:一般方法如下: fclose(FilePointer);fclose(FilePointer);   或:或:if(fclose(filepointer)= =NULL)if(fclose(filepointer)= =NULL){printf(“close error”);exit(2);} {printf(“close error”);exit(2);} 使用使用 FILEFILE 类型和类型和 fopen( )fopen( ) 、、 fclose( )fclose( ) 函数函数应包含应包含 stdio.hstdio.h

Page 13: 开关文件

1. 1. 输入输出字符输入输出字符 11 )) I/OI/O 字符字符 ch=fgetc(fp);ch=fgetc(fp);

fputc(ch,fp);fputc(ch,fp);

putchar( ch)putchar( ch) 实际上是用实际上是用 fputc(ch, fp)fputc(ch, fp) 定义的一个宏定义的一个宏 ::##define putchar(ch) fputc(ch, stdout) define putchar(ch) fputc(ch, stdout) 默认输出到标准输出设备默认输出到标准输出设备 -- 显示器即标准输出文件显示器即标准输出文件 stdoutstdout 。。 22 ))判断文件尾判断文件尾 fgetc( ) fgetc( ) 在读到文件末尾时,返回文件结束标志在读到文件末尾时,返回文件结束标志EOFEOF ((在在 stdio.hstdio.h 中定义为中定义为 -1-1 。此标志只适合于文本文件,。此标志只适合于文本文件,二进制文件中的数值二进制文件中的数值 -1-1 会与其相混,造成提前结束。会与其相混,造成提前结束。 常用常用 feof( )feof( ) 函数测试文件尾。若是文件结函数测试文件尾。若是文件结束返回值束返回值 11 。它既可以用于二进制文件也可。它既可以用于二进制文件也可以用于文本文件。以用于文本文件。

读写文件读写文件

Page 14: 开关文件

2. 2. 输入输出数据块输入输出数据块 一次可一次可 I/OI/O 一个数组或结构体类型的数据,后者与其它高一个数组或结构体类型的数据,后者与其它高级语言的记录读写。级语言的记录读写。ANSI C ANSI C 设置了两个函数:设置了两个函数: fread(buffer, size, count, fp)fread(buffer, size, count, fp)

fwrite(buffer, size, count, fp)fwrite(buffer, size, count, fp) [[ 例例 ] ] 从键盘输入从键盘输入 55 个学生的数据,存为文本文件,然后读回个学生的数据,存为文本文件,然后读回验证验证。。3. 3. 格式化格式化 I/OI/O

fprintf(fp,formstr, outlist)fprintf(fp,formstr, outlist)

fscanf(fp, ,formstr, outlist)fscanf(fp, ,formstr, outlist)

Page 15: 开关文件

文件的读写字符 I/O:fputc 与 fgetc

fputc函数原型: int fputc(int c, FILE *fp)功能:把一字节代码 c 写入 fp 指向的文件中返值:正常,返回 c; 出错,为 EOF

fgetc函数原型: int fgetc(FILE *fp)功能:从 fp 指向的文件中读取一字节代码

返值:正常,返回读到的代码值 ; 读到文件尾或出错,为 EOF

文件 I/O与终端 I/O#define putc(ch,fp) fputc(ch,fp)#define getc(fp) fgetc(fp)#define putchar( c ) fputc(c,stdout)#define getchar( ) fgetc(stdin)

Page 16: 开关文件

判断二进制文件是否结束 while(!feof(fp)) { c=fgetc(fp); …….. }

例 文件拷贝

例 从键盘输入字符,逐个 存到磁盘文件中,直到 输入‘ #“ 为止#include <stdio.h>main(){ FILE *fp; char ch,*filename=“out.txt”; if((fp=fopen(filename,"w"))==NULL) { printf("cannot open file\n");

exit(0); } printf("Please input string:"); ch=getchar(); while(ch!='#') { fputc(ch,fp); putchar(ch); ch=getchar(); } fclose(fp);}

例 读文本文件内容, 并显示

#include <stdio.h>main(){ FILE *fp; char ch,*filename=“out.txt”; if((fp=fopen(filename,”r"))==NULL) { printf("cannot open file\n"); exit(0); } while((ch=fgetc(fp))!=EOF) putchar(ch); fclose(fp);}

判断文本文件是否结束

feof函数原型: int feof(FILE *fp)功能:判断文件是否结束返值:文件结束,返回真(非 0 );文件未结束,返回 0

#include <stdio.h>main(){ FILE *in, *out; char ch,infile[10],outfile[10]; scanf("%s",infile); 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"); exit(0); } while (!feof(in)) fputc(fgetc(in), out); fclose(in); fclose(out);}

Page 17: 开关文件

数据块 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 一般用于二进制文件的输入 / 输出

Page 18: 开关文件

例 float f[2]; FILE *fp; fp=fopen(“aa.dat”,“rb”); fread(f,4,2,fp);

for(i=0;i<2;i++) 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);

Page 19: 开关文件

Ch12_3.c例 从键盘输入 4 个学生数据,把他们转存到磁盘文件中去#include <stdio.h>#define SIZE 2struct student_type{ char name[10]; int num; int age; char addr[15];}stud[SIZE];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(); display();}

void save(){ FILE *fp; int i; if((fp=fopen("d:\\fengyi\\exe\\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);}

void display(){ FILE *fp; int i; if((fp=fopen("d:\\fengyi\\exe\\stu_dat","rb"))==NULL) { printf("cannot open file\n");

return; } 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);}

Page 20: 开关文件

格式化 I/O:fprintf 与 fscanf函数原型:int fprintf(FILE *fp,const char *format[,argument,…])int fscanf(FILE *fp,const char *format[,address,…])

功能:按格式对文件进行 I/O 操作返值:成功 , 返回 I/O 的个数 ; 出错或文件尾 , 返回 EOF

例 fprintf(fp,“%d,%6.2f”,i,t); // 将 i 和 t 按 %d,%6.2f 格式输出到 fp 文件 fscanf(fp,“%d,%f”,&i,&t); // 若文件中有 3,4.5 , 则将 3 送入 i, 4.5 送入 t

例 从键盘按格式输入数据存到磁盘文件中去Ch12_70.c

#include <stdio.h>main(){ char s[80],c[80]; int a,b; FILE *fp; if((fp=fopen("test","w"))==NULL) { puts("can't open file"); exit() ; } fscanf(stdin,"%s%d",s,&a);/*read from keaboard*/ fprintf(fp,"%s %d",s,a);/*write to file*/ fclose(fp); if((fp=fopen("test","r"))==NULL) { puts("can't open file"); exit(); } fscanf(fp,"%s%d",c,&b);/*read from file*/ fprintf(stdout,"%s %d",c,b);/*print to screen*/ fclose(fp);}

Page 21: 开关文件

字符串 I/O: fgets 与 fputs函数原型: char *fgets(char *s,int n,FILE *fp)

int fputs(char *s,FILE *fp)功能:从 fp 指向的文件读 / 写一个字符串返值:

fgets 正常时返回读取字符串的首地址;出错或文件尾,返回NULL

fputs 正常时返回写入的最后一个字符;出错为 EOF

例 从键盘读入字符串存入文件,再从文件读回显示Ch12_400.c

fgets从 fp所指文件读 n-1个字符送入 s 指向的内存区 ,并在最后加一个‘ \0’(若读入 n-1个字符前遇换行符或文件尾( EOF)即结束 )fputs把 s 指向的字符串写入 fp指向的文件

#include<stdio.h>main(){ FILE *fp; char string[81]; if((fp=fopen("file.txt","w"))==NULL) { printf("cann't open file");exit(0); } while(strlen(gets(string))>0) { fputs(string,fp); fputs("\n",fp); } fclose(fp); if((fp=fopen("file.txt","r"))==NULL) { printf("cann't open file");exit(0); } while(fgets(string,81,fp)!=NULL) fputs(string,stdout); fclose(fp);}

Page 22: 开关文件

1. 1. 返回文件开头返回文件开头 rewind(fp)rewind(fp) 2. 2. 随机定位随机定位 fseek(fp, fseek(fp, 偏移量,起始点)偏移量,起始点) 起始点 名字 数字表示起始点 名字 数字表示文件开始 文件开始 SEEK_SET 0SEEK_SET 0文件当前位置 文件当前位置 SEEK_CUR 1SEEK_CUR 1文件末尾 文件末尾 SEEK_END 2 SEEK_END 2 偏移量可以用 偏移量可以用 +/-+/- 表示向前或向后移动。 表示向前或向后移动。

文件定位文件定位

Page 23: 开关文件

文件的定位几个概念

文件位置指针 ----- 指向当前读写位置的指针读写方式

顺序读写:位置指针按字节位置顺序移动,叫 ~随机读写:位置指针按需要移动到任意位置,叫 ~

rewind 函数函数原型: void rewind(FILE *fp)功能:重置文件位置指针到文件开头返值:无

例 对一个磁盘文件进行显示和复制两次操作

#include <stdio.h>main(){ FILE *fp1,*fp2; fp1=fopen("d:\\fengyi\\bkc\\ch12_4.c","r"); fp2=fopen("d:\\fengyi\\bkc\\ch12_41.c","w"); while(!feof(fp1)) putchar(getc(fp1)); rewind(fp1); while(!feof(fp1)) putc(getc(fp1),fp2); fclose(fp1); fclose(fp2);}

Page 24: 开关文件

fseek 函数函数原型: int fseek(FILE *fp,long offset,int whence)功能:改变文件位置指针的位置返值:成功,返回 0 ;失败,返回非 0 值

文件指针位移量(以起始点为基点 , 移动的字节数 )>0 向后移动<0 向前移动

起始点文件开始 SEEK_SET 0文件当前位置 SEEK_CUR 1文件末尾 SEEK_END 2

例 fseek(fp,100L,0); fseek(fp,50L,1); fseek(fp,-10L,2);

ftell 函数函数原型: long ftell(FILE *fp)功能:返回位置指针当前位置 ( 用相对文件开头的位移量表示 )返值:成功,返回当前位置指针位置;失败,返回 -1L ,

例 磁盘文件上有 3 个学生数据,要求读入第 1 , 3 学生数据并显示Ch12_5.c

main(){ int i; FILE *fp; if((fp=fopen("studat","rb"))==NULL) { printf("can't open file\n");exit(0); } for(i=0;i<3;i+=2) { fseek(fp,i*sizeof(struct student_type),0); fread(&stud[i],sizeof(struct student_type),1,fp); printf("%s %d %d %s\n", stud[i].name,stud[i].num,stud[i].age,stud[i].addr); } fclose(fp);}

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

#include"stdio.h" main() { FILE *fp; char filename[80]; long length; gets(filename); fp=fopen(filename,"rb"); if(fp==NULL) printf("file not found!\n"); else { fseek(fp,0L,SEEK_END); length=ftell(fp); printf("Length of File is %1d bytes\n",length); fclose(fp); } }

例 求文件长度 (ch12_101.c)

Page 25: 开关文件

例如:例如: exfile1.cexfile1.c

exfcopy.cexfcopy.c

exfcpy2.cexfcpy2.c

exrw1.cexrw1.c

exsp1.cexsp1.c

exwst.cexwst.c