370 likes | 523 Views
第九章 文件. 9.1 文件概述 一、文件的概念 *文件: 存储在外部介质上的数据的集合 数据是以 文件的形式 存放在 外部介质 上, OS 是以文件为单位实施数据管理的 C 语言把文件看成是一个字节或字符序列 二进制文件 文本文件. 二进制文件 --- 数据按其在内存中的存储形式存放 文本文件 ---- 文件以字符为单位 , 存储与输入 / 出存在翻译过程. 01011100. 11010101. 10011011. 11001101. a. b. a. d. h. f. s. n. C 语言的文件是一个字节流或字符流
E N D
第九章 文件 9.1 文件概述 一、文件的概念 *文件:存储在外部介质上的数据的集合 数据是以文件的形式存放在外部介质上, OS是以文件为单位实施数据管理的 C语言把文件看成是一个字节或字符序列 二进制文件 文本文件
二进制文件---数据按其在内存中的存储形式存放二进制文件---数据按其在内存中的存储形式存放 文本文件----文件以字符为单位, 存储与输入/出存在翻译过程 01011100 11010101 10011011 11001101 a b a d h f s n C语言的文件是一个字节流或字符流 ------流式文件stream 文件类型:读/写一致的约定
二、缓冲文件系统 系统自动在内存为每个打开的文件开辟一个缓冲区,输出数据到文件时,先把数据送到缓冲区,缓冲区满后再送到外部介质。从文件读入数据时,先从外部介质上读入一批数据到缓冲区,再从缓冲区取出数据送给程序变量。 缓冲区的大小由编译程序决定,相应函数在stdio.h中 内存 外部介质 输入 缓冲区 文件 程序 数据区 输出
缓冲区 缓冲区 从键盘输入数据写入文件one one one 从文件one读取数据显示(写到)屏幕
三、3个标准输入/出文件 stdin 标准输入文件----键盘 stdout 标准输出文件----显示器/打印机 stderr 标准错误输出文件----显示器 四、文件类型指针 每个文件要使用必须先打开, 打开时在内存开辟一个区,存放文件的有关信息, 这些信息保存在一个结构体类型的变量中 该关键字类型由系统定义,名为FILE <stdio.h>
typedef struct {int level; /* fill/empty level of buffer */ unsigned flags; /* File status flags文件存取标识 */ char fd; /* File descriptor 文件描述符*/ unsigned char hold; /* Ungetc char if no buffer */ int bsize; /* Buffer size */ unsigned char *buffer; /* Data transfer buffer 指向缓冲区的指针*/ unsigned char *curp; /* Current active pointer 当前传送的字符指针*/ unsigned istemp; /* Temporary file indicator */ short token; /* Used for validity checking */ }FILE;
typedef struct {int level; //缓冲区空/满 unsigned flags; ……….. int bsize; //缓冲区大小 unsigned char *buffer; //指向缓冲区的指针 unsigned char *curp; //当前传送的字符指针 …………… }FILE; buffer • 5678 ab cd<CR>1345 6789 • …… bsize curp 输入/输出缓冲区
9.2 文件操作 一、文件操作方式: 文件的一般操作方式为: 打开文件读数据关闭 建新文件写数据关闭 打开一个文件,该文件就拥有: 一个FILE型数据,一个buffer 程序开始运行时系统自动打开3个标准文件
二、文件的打开与关闭 方法:FILE *fp; fp=fopen(文件名,操作方式); ……………… fclose(fp); 。fp是指向FILE结构的指针,称为文件指针 。如果打开文件成功,返回正常值 否则返回空指针NULL 。文件名是一个字符串,可包含路径 。标准输入/出文件由系统打开 。文件操作结束时应关闭文件,否则会丢失数据 。正常关闭文件会返回0,否则返回非0 fp=fopen(“a:try.txt”, “r”); fp2=fopen(“c:\\new\\abc.cpp”, “w”);
三、文件读写 1.char fputc(char ch, FILE *fp) 把ch输出到fp对应的文件中去。 返回值:成功返回ch 否则返回EOF(-1) 2.char fgetc(FILE *fp) 从文件fp中读取一个字符 读到文件结束符时返回EOF #define getchar( ) fgetc(stdin) #define putchar(c) fputc(c, stdout)
char fputc(char ch, FILE *fp) int main( ) { FILE *fp; char ch; fp=fopen("d:\\try.txt","w"); ch=getchar( ); while(ch!='#') {fputc(ch,fp); ch=getchar(); } fclose(fp); return 0; }
char fgetc(FILE *fp) int main( ) {char ch; FILE *fp; fp=fopen("d:\\try.txt", "r"); ch=fgetc(fp); while(ch!=EOF) {putchar(ch); ch=fgetc(fp); } fclose(fp); return 0; }
void writefile_c(FILE *fp) {char ch; ch=getchar(); while(ch!='#') {fputc(ch,fp); ch=getchar(); } } void readfile_c(FILE *fp) {char ch; ch=fgetc(fp); while(ch!=EOF) {putchar(ch); ch=fgetc(fp); } }
3.int feof(FILE *fp) 判断文件fp是否结束 结束: 返回1 没有结束:返回0 4.int putw(int num, FILE *fp) int getw(FILE *fp) 读写整型数据
int putw(int num, FILE *fp) int main( ) { FILE *fp; int num; fp=fopen("d:\\try\\ttt.dat", "wb"); scanf("%d",&num); while(num!=-1) {putw(num,fp); scanf("%d",&num); } fclose(fp); }
int getw(FILE *fp) int main( ) { FILE *fp; int num; fp=fopen("d:\\try\\ttt.dat","rb"); num=getw(fp); while(!feof(fp)) {printf("%d ",num); num=getw(fp); } fclose(fp); }
5.char *fgets(char *str, int num, FILE *fp) 从指定的文件中最多读取num-1个字符放到str处. 读到num-1个字符 或遇到回车、或文件结束时停止。 碰到文件结束返回NULL。 int fputs(char *str, FILE *fp) 把字符串写到指定的文件
int fputs(char *str, FILE *fp) int main( ) { FILE *f1; char str[81]; f1=fopen("d:\\try\\ccc.txt", "w"); gets(str); while(str[0]!='\0') { fputs(str,f1); // fputs("\n",f1); gets(str); } fclose(f1); }
char *fgets(char *str, int num, FILE *fp) int main( ) { FILE *fp; char str[81]; fp=fopen("d:\\try\\ccc.txt","r"); while(fgets(str,80,fp)!=NULL) printf("%s",str); fclose(fp); return 0; }
*文件关闭后,文件大小由OS登记, 故文件结束无明显标识 *读取文本文件时,若读到的字符为EOF,表示文件结束 读取二进制文件时,feof(fp)表示文件结束。 *操作时,一般文本文件用w、r方式打开 二进制文件用wb、rb方式打开 void exit(int status) process.h stdlib.h void _exit(int status) stdio.h 使程序立即正常终止,status被传递给系统 0:正常终止 非0:程序中有错误
00000000 00000000 00000000 00000000 00110000 00000000 00000000 00110111 00000000 01100101 01000010 00000000 01100001 01000010 01011001 00110001 00000000 00010100 01100010 01100011 00000000 00000000 00000000 00000000 00000000 struct student {int num; char name[8],class[5]; int age,score; }; 二进制文件
struct student {int num; char name[8],class[5]; int age,score; }; 00110001 00110000 00110001 00100000 01100001 01100010 01100011 00100000 00110000 00110111 01000010 00110001 00100000 00110010 00110000 00100000 00111000 00111001 文本文件
文件追加 int main( ) {FILE *fp; char ch; if((fp=fopen(“d:\\ccc.txt”, “a”))==NULL) {printf(“\n cannot open file!\n”); exit(0); } while((ch=getchar())!=‘\n’) fputc(ch,fp); fclose(fp); return 0; }
文件追加 int main( ) {FILE *fp; char ch,filename[20]; printf(“Input filename to append:”); gets(filename); if((fp=fopen(filename,”a”))==NULL) {printf(“\n cannot open file!\n”); exit(0); } while((ch=getchar())!=’\n’) fputc(ch,fp); fclose(fp); return 0; }
文件追加 void append(char*filename ) {FILE *fp; char ch; if((fp=fopen(filename,”a”))==NULL) {printf(“\n cannot open file!\n”); exit(0); } while((ch=getchar())!=’\n’) fputc(ch,fp); fclose(fp); }
int main( ) {FILE *in,*out; char ch,inname[20],outname[20]; printf(“input the file name to copy :”); gets(inname); printf(“input the file name to copy to:”); gets(outname); if((in=fopen(inname,”r”))==NULL) {printf(“file not open!”); exit(1);} if((out=fopen(outname,”w”))==NULL) {printf(“cannot open file”); exit(1);} while((ch=fgetc(in))!=EOF) fputc(ch, out); fclose(in); fclose(out); } 文件复制
文件合并 int main( ) {FILE *f1,*f2,*f3; char ch; f1=fopen(“file1.txt”, “r”); f2=fopen(“file2.txt”, “r”); f3=fopen(“file3.txt”, “w”); while((ch=fgetc(f1))!=EOF) fputc(ch,f3); while((ch=fgetc(f2))!=EOF) fputc(ch,f3); fclose(f1);fclose(f2); fclose(f3); return 0; }
6.int fread(void *buffer,int size,int count,FILE *fp) 从fp所指向的流中读取count个长度为size的字节, 并把他们放到buffer所指向的内存单元中,文件位置指示器随着读取的字节数而下移。该函数返回读取的count值 7.int fwrite(void *buffer,int size,int count,FILE *fp) 从buffer所指向的缓冲区中取出count个size字节的内容写到fp所指向的流中。该函数返回写入的count值
8.void fseek(FILE *fp, long offset, int origin) 把文件位置指针从某个位置开始往前(offset<0)移 或往后(offset>0)移offset个字节 #define SEEK_SET 0 文件头 #define SEEK_CUR 1 当前位置 #define SEEK_END 2 文件尾 用文件定位实现文件的随机读写 9.void rewind(FILE *fp) 使文件位置指针指向文件头
读入4个学生的数据,存入磁盘文件 #define N 4 struct student {char name[10]; int num; int age; int score; }; //放入文件stu.dat zhangsan 105 20 98 lisi 103 19 76 wanwu 108 21 87 maliu 104 19 69
struct student {char name[10]; int num; int age; int score; }; int main( ) {int i,num; struct student one; FILE *fi; fi=fopen("d:\\stu.dat", "wb"); for(i=0; i<N; i++) { scanf("%s %d %d %d",one.name,&one.num, &one.age, &one.score); fwrite(&one,sizeof(struct student),1,fi); } fclose(fi); } 从键盘读取学生数据,写入文件1
struct student {char name[10]; int num; int age; int score; }; int main( ) {int i,num; struct student one[N]; FILE *fi; fi=fopen("d:\\stu.dat", "wb"); for(i=0; i<N; i++) scanf("%s %d %d %d",one[i].name,&one[i].num, &one[i].age, &one[i].score); fwrite(one,sizeof(struct student),N,fi); fclose(fi); } 从键盘读取学生数据,写入文件2
int main( ) {FILE *fp; int i; struct student one[N];int num; fp=fopen("d:\\data\\stu.dat","rb"); //打开文件 if(fp==NULL) //没有找到文件 {printf("can not open file\n"); exit(0); } fread(one,sizeof(struct student),4,fp); fclose(fp); scanf("%d",&num); for(i=0; i<N; i++) { if(one[i].num==num) {printf("%-10s%5d\n",one[i].name,one[i].score); break; } } if(i>=N) printf("not found\n");} 从文件中查询
int main( ) {FILE *fp; int i; struct student one[N]; int num; fp=fopen("d:\\stu.dat","rb"); //打开文件 fseek(fp,sizeof(struct student)*5,SEEK_SET); fread(one,sizeof(struct student),N,fp); fclose(fp); scanf("%d",&num); for(i=0; i<N; i++) { if(one[i].num==num) {printf("%-10s%5d\n",one[i].name,one[i].score); break; } } if(i>=N) printf("not found\n");}
10.int fprintf(FILE *fp, char *format,args,…) int fscanf(FILE *fp, char *format,args,…) 将4个学生的数据存入磁盘文件 #define N 4 struct student {char name[10]; int num; int age; int score; }stu[N]; //用编辑器生成文件stu.txt zhangsan 105 20 98 lisi 103 19 76 wanwu 108 21 87 maliu 104 19 69
int main( ) {FILE *fp; int i,j; struct student one[20]; int num; fp=fopen("d:\\stu.txt","r"); //打开文件 if(fp==NULL){printf("can not open file\n"); exit(0); } i=0; while(!feof(fp)) { fscanf(fp,"%s %d %d %d", one[i].name, &one[i].num,&one[i].age,&one[i].score); i++; } fclose(fp); scanf("%d",&num); for(j=0; j<i; j++) { if(one[j].num==num) {printf("%-10s%5d\n",one[j].name,one[j].score); break; } } }