第9章 文件 学习目的与要求: 熟练掌握文件指针的使用 掌握与文件相关的函数 能够利用文件相关函数实现各种操作
基本内容 C文件简介 打开与关闭文件 文件的读写 文件定位与随机读写 本章小结
C文件简介 文件一般指存贮在外部存储器(如磁盘)上数据的集合。对文件有两种操作:一种操作是读文件,是将存贮在文件上的数据输入内存;另一种操作是写文件,是将内存中的数据输送至文件。 C语言将文件看作是一个字符(字节)的序列,即由一个个字符顺序组成。根据数据的组织形式,文件可分为ASCII码文件和二进制文件。 文本文件: ASCII文件,每个字节存放一个字符的ASCII码。 二进制文件:数据按其在内存中的存储形式原样存放
存储量大、速度慢、便于对字符操作 存储量小、速度快、便于存放中间结果 文本文件特点: 存储量大、速度慢、便于对字符操作 如short型数1234 0000010011010010 内存存储形式 0000100011010010 二进制形式 00110001001100100011001100110100 ASCII形式 二进制文件特点: 存储量小、速度快、便于存放中间结果
文件结构体FILE 每一个与文件相关的流都有一个FILE结构体类型的对象。FILE结构体在头文件“stdio.h”中定义。FILE中存放有关文件的信息,如文件名、文件状态、文件当前位置等。 FILE具体定义如下: typedef struct { short level; //缓冲区“满”或“空”的程度 unsigned flags; //文件状态标志 char fd; //文件描述符 unsigned char hold; //无缓冲区时,不读取字符 short bsize; //缓冲区的大小 unsigned char *buffer; //数据缓冲区的位置 unsigned char *curp; //指针当前的指向 unsigned istemp; //临时文件指示器 short token; //用于有效性检查 }FILE;
文件结构体FILE 定义文件指针变量的一般形式为: FILE *文件指针变量名; 例如:FILE *fp; 定义fp是指向FILE类型的指针变量 说明: FILE必须大写。 只有通过文件指针变量才能调用相应的文件。 指向文件的指针变量并不是指向外存上的数据文件的开头,而是指向内存中的文件信息区的开头。 有n个文件要定义n个文件指针变量,分别对应各个文件。
基本内容 C文件简介 打开与关闭文件 文件的读写 文件定位与随机读写 本章小结
打开文件 文件读写之前首先要“打开”文件,读写结束后应关闭该文件。用库函数fopen()来打开文件。 库函数fopen() 原型声明为: FILE* fopen(char* filename,char* mode);
打开文件说明 filename是要打开的文件名,是一个字符串,可带有路径。 mode是打开文件的方式,是一个字符串,具体为: “r+/rb+” (读写) “a/ab” (追加) “w/wb” (只写) “r/rb” (只读) “w+/wb+” (读写) “a+/ab+” (读写) 为输入打开一个文本/二进制文件 为输出打开一个文本/二进制文件 为读/写打开一个文本/二进制文件 为读/写建立一个新的文本/二进制文件 向文本/二进制文件尾追加数据 文件使用方式 含义
打开文件说明 如果能正常实现“打开”操作,fopen()返回一个指向FILE类型的指针,该指针与文件名联系在一起。如果不能正常实现“打开”操作,fopen()将返回一个空指针NULL。 FILE* fp; if ((fp=fopen("file","r"))==NULL) { printf("cannot open the file.\n"); exit(0); } 系统定义了3个文件指针变量stdin、stdout和stderr,分别指向标准输入流、标准输出流和标准出错输出流,可以通过这3个指针变量对文件进行操作
关闭文件 对文件执行完读写操作后应及时关闭文件。关闭文件操作可将缓冲区中的数据输出到文件,并释放文件指针。 库函数fclose () 原型声明为: int fclose(FILE* fp); 例如:fclose(fp);
基本内容 C文件简介 打开与关闭文件 文件的读写 文件定位与随机读写 本章小结
文件的读写 当文件按指定方式打开后,就可以对文件进行“读”或“写”操作了。“读”操作是指从文件中读取数据,“写”操作是指将内存中的数据写入到文件中。 常用的读写函数有: 单个字符读写函数:fgetc和fputc 字符串的读写函数:fgets和fputs 数据块的读写函数:fread和fwrite 格式化读写函数: fscanf和fprintf
fputc函数 fputc函数的原型为: int fputc(int ch, FILE* fp); 功能: 将字符ch写到文件指针fp所指向的文件的当前写指针的位置。 返回值:在正常调用情况下,函数返回读取字符的ASCII码值,出错时,返回EOF(-1)。 通过指向标准输出流的指针变量stdout,可以将字符ch输出到显示器上,即:fputc(ch,stdout); 其作用是将字符ch输出到标准终端。
fputc函数应用举例 通过键盘输入一行字符,将其写到文件中。 #include <stdio.h> #include <stdlib.h> int main() { FILE *fp; char ch, filename[20]; printf("请输入文件名:\n"); gets(filename); if((fp=fopen(filename, "w"))==NULL) //建立一个新文件 { printf("无法打开此文件\n"); return 1; }
fputc函数应用举例 printf("请输入字符串:\n"); while((ch=getchar())!='\n') { fputc(ch,fp); putchar(ch); } putchar('\n'); fclose(fp); return 0;
fgetc函数 fgetc()函数的原型为: int fgetc(FILE* fp); 返回值:返回所读取的一个字节。如果读到文件末尾或者读取出错时返回EOF。 可以通过指向标准输入流的指针变量stdin,接收键盘读入的字符,即:ch=fgetc(stdin); 其作用是将从键盘输入的字符赋给字符变量ch。
fgetc函数应用举例 将上例中的文件内容复制到另一个文件中。 #include <stdio.h> #include <stdlib.h> int main() { FILE *fp; char ch, filename1[20],filename2[20]; printf("请输入源文件名:\n"); gets(filename1); printf("请输入目标文件名:\n"); gets(filename2); if((fp1=fopen(filename1, "r"))==NULL) { //打开已存在的文件 printf("该文件不存在\n"); return 1; }
fgetc函数应用举例 if((fp2=fopen(filename2, "w"))==NULL) //建立一个新文件 { printf("无法打开此文件\n"); return 1; } while((ch=fgetc(fp1))!=EOF) { fputc(ch,fp2); //写入fp2文件 putchar(ch); //输出到屏幕显示 putchar('\n'); fclose(fp1); fclose(fp2); return 0; while(!feof(fp1))
fread和fwrite函数 fgetc()和fputc()函数每次只能读写一个字节,若要读写一个数据块,就需要用到fread()和fwrite()函数。 fread()和fwrite()函数的原型为: int fread(void *ptr, unsigned int size_byte, unsigned int count , FILE *fp); int fwrite(void *ptr, unsigned int size_byte, unsigned int count, FILE *fp); 其中: ptr:是一个指针,指向数据块读写时用于存放数据的内存的首地址; size_byte:表示一个数据块的字节数,即一个数据块的大小; count:表示要读写的数据块的个数; fp:表示文件指针。
fread和fwrite函数功能 fread()函数从文件fp当前位置指针处读取count个长度为size_byte大小(字节表示)的数据块,存放到ptr所指向的存储单元中。若操作成功,文件位置指针前进count*size_byte个字节,并返回成功读出的元素个数。若文件读取出错或文件遇到结束,实际读出的数目可能小于count数。 fwrite()函数将ptr所指向存储单元中的数据,以每个元素size_byte字节大小,写入fp文件共count个元素。若写入成功,文件位置指针前进成功写入的字节数,函数返回写入元素的数目。若文件结束或写入不成功,返回值可能小于count数。
fread和fwrite函数应用举例 将一组学生信息写入文件student.dat,然后读出并在屏幕上显示出来。 #include<stdio.h> #include<stdlib.h> #define SIZE 3 //学生数量 //定义一个结构体类型Student typedef struct { int num; //学号 char name[15]; //学生姓名 char sex; //性别 int age; //年龄 }Student;
fread和fwrite函数应用举例 //编写一个存储信息函数,将信息写入文件 void save(Student *pw){ FILE *fp; short i ; if((fp=fopen("student.dat", "wb"))==NULL) { printf("Cannot create the file."); exit(1); } for(i=0;i<SIZE;i++){ fwrite(pw,sizeof(Student),1,fp); //写入文件student.dat pw++; fclose(fp);
fread和fwrite函数应用举例 //编写一个读取信息函数,将信息从文件读出 void load(Student *pr){ FILE *fp; short i ; if((fp=fopen("student.dat","rb"))==NULL){ printf("Cannot open the file."); exit(1) ; } for(i=0;i<SIZE; i++){ fread(pr, sizeof(Student),1,fp); pr++; fclose(fp);
fread和fwrite函数应用举例 int main(){ Student in[SIZE],out[SIZE]; short i; printf("请输入%d个学生的信息:\n",SIZE); printf("学号 姓名 性别 年龄\n"); for(i=0;i<SIZE;i++){//将学生信息存入数组out[SIZE] scanf("%d",&out[i].num); getchar(); //屏蔽空格或回车键 scanf("%s",out[i].name); scanf("%c",&out[i].sex); scanf("%d",&out[i].age); }
fread和fwrite函数应用举例 save(out); //调用存储函数将数组out[SIZE]信息存入文件 load(in); //调用读文件函数将信息读出存入数组in[SIZE] printf("\n输出学生的相关信息:\n"); printf(" 学号 姓名 性别 年龄\n"); for(i=0; i<SIZE;i++){ printf("%5d%10s",in[i].num,in[i].name); printf("%5c%6d\n",in[i].sex,in[i].age); } return 0;
fscanf函数与fprintf函数 fscanf()与fprintf()是格式化读写函数,其作用和使用方法与scanf()和printf()相似,只不过是对磁盘文件的操作,参数增加了一个文件指针。 调用方式为: fscanf(FILE* fp, 格式字符串, 输入表列); fprintf(FILE* fp, 格式字符串, 输出表列); 例如: //从磁盘文件fp读入一个字符存入ch中,读入一个整数存入i中fscanf(fp,"%c,%d",&ch,&i); fprintf (fp,"%c,%d",'a',10); //将字符a与整数10写入文件fp中
fscanf函数与fprintf函数应用举例 将一组商品信息存入goods.dat文件中,然后从文件中读出并显示出来。 #include <stdio.h> #define N 3 typedef struct{ int num; //商品编号 char name[20]; //商品名称 float price; //商品价格 }Goods; int main() { FILE *fp; Goods g; int i;
fread和fwrite函数应用举例 if((fp=fopen("goods.dat","w"))==NULL) { printf("cannot open the file.\n"); return 1; } printf("输入商品信息\n"); printf("编号、名称、价格\n"); for(i=1;i<=N;i++) { scanf("%d ",&g.num); scanf("%s %f",g.name,&g.price); fprintf(fp, "%d %s %f\n",g.num,g.name,g.price); fclose(fp);
fread和fwrite函数应用举例 if((fp=fopen("goods.dat","r"))==NULL) { printf("cannot open the file.\n"); return 1; } printf("\n输出文件中的数据\n"); printf(" 编号 商品名称 商品价格\n"); for(i=1;i<=N;i++) { fscanf(fp, "%d %s %f",&g.num,g.name,&g.price); fprintf(stdout, "%4d%10s%12.2f\n",g.num,g.name,g.price); fclose(fp); return 0;
fgets函数与fputs函数 fgets()和fguts()函数的作用是读写一个字符串。 函数原型:char *fgets(char*str,int n,FILE*fp); 功能:从文件指针fp指定的文件中,读取长度最大为n-1个字符的字符串,在串尾自动加上串结束标志‘\0’后,将字符串存入str 中。若操作成功,函数返回str,若读到文件尾或出错,返回NULL。 函数原型:int fputs(char *str, FILE*fp); 功能:向文件指针fp指定的文件写入由str指向的字符串,‘\0’不写入文件。若操作成功,返回非零值,否则返回EOF。
fgets函数与fputs函数应用举例 将一个字符串写入文件中,然后读出在屏幕上显示。 #include<stdio.h> #define Length 10 //串长上界 int main() { FILE*fp; char str[Length]; if((fp=fopen("file.txt","w"))==NULL){ printf("can not open the file. "); return 1; } fputs(" Hello world!\n I am a programmer. \n",fp); fclose(fp);
fgets函数与fputs函数应用举例 //为读出打开文件File.txt,fp指向该文件 if((fp=fopen("file.txt","r"))==NULL){ printf ("cannot open the file. "); return 1; } //读文件,将信息存入字符串str while(fgets(str,3,fp)!=NULL) printf("%s",str); //屏幕显示串信息 fclose(fp); return 0;
基本内容 C文件简介 打开与关闭文件 文件的读写 文件定位与随机读写 本章小结
定位和随机读写简介 系统在文件中设置了一个隐含的文件位置指针,其最小值为0,即文件的起始位置,最大值为文件的长度,即文件包含的字节数。文件刚打开时,位置指针指向文件的首部,顺序读写文件时,每次位置指针前进实际读写的字节数。若要从文件的任意位置读写,即随机读写,就要将文件位置指针移动到要读写的字节位置,这就要用到文件的位置定位函数。
文件定位函数 (1)rewind函数 (2)fseek函数 函数原型:void rewind(FILE *fp); 函数原型:int fseek(FILE*fp,long int offset,int whence ) 功能:将fp指向的文件位置指针移动到特定位置,即将文件位置指针定位到距离whence偏移offset字节处。操作成功返回0,否则返回非0值。 数值 1 2 whence常量 SEEK_SET SEEK_CUR SEEK_END 文件起始位置 含 义 文件位置指针的当前位置 文件尾部
文件定位函数 (3)ftell函数 函数原型:long int ftell (FILE*fp) 功能:将fp指向的文件位置指针移动到特定位置,即将文件位置指针定位到距离whence偏移offset字节处。操作成功返回0,否则返回非0值。
文件定位函数应用举例 将字符串写入文件,将文件位置指针偏移量显示在屏幕上。 #include <stdio.h> int main() { FILE*fp; char str[]="Hello",*ps=str; if((fp=fopen("file.dat","wb+"))==NULL){ printf("cannot create the file.\n"); return 1; } printf("文件的位置指针如下:\n"); while(*ps!= '\0'){ printf("%d\t",ftell(fp));
文件定位函数应用举例 fputc(*ps,fp); ps++; } printf("%d\n",ftell(fp)); //位置指针在EOF处 rewind(fp); //位置指针回首 printf("%d\t",ftell(fp)); putchar(fgetc(fp)); //输出文件首字母 fseek(fp,-1L,SEEK_END); printf("\n%d\t",ftell(fp)); putchar(fgetc(fp)); //输出文件尾部字母 putchar('\n'); fclose(fp); return 0;
基本内容 C文件简介 打开与关闭文件 文件的读写 文件定位与随机读写 本章小结
本章小结 本章主要介绍了C文件常用的几种函数,并通过例子说明了各函数的使用方法,当对文件进行操作时首先要打开文件,然后利用文件的各种函数对文件内容进行操作,当文件使用结束后,应养成关闭文件的习惯,以防文件内容的丢失。 常用的缓冲文件系统函数主要有: 文件的打开与关闭:fopen()、fclose() 文件定位函数:fseek()、rewind()、ftell() 文件的读写函数:fgetc()、fputc()、fgets()、fputs()、fread()、fwrite()、fscanf()、fprintf() 文件状态函数:feof()