第13章文件C文件概述文件类型指针文件的打开与关闭文件的读写文件的定位出错的检测文件输入输出小结回顾位运算是C语言的一种特殊运算功能,它是以二进制位为单位进行运算的。位运算符可以与赋值符一起组成复合赋值符。利用位运算可以完成汇编语言的某些功能,如置位,位清零,移位等。位段在本质上也是结构类型,不过它的成员按二进制位分配内存。其定义、说明及使用的方式都与结构相同目标了解文件的概念。了解文件类型指针的定义和含义。掌握文件操作的相关标准函数。了解文件定位的操作及相关的标准函数。了解出错检测函数的作用。了解非缓冲文件系统的各种操作。13.1C文件概述文件:存储在外部介质上数据的集合,是操作系统数据管理的单位按数据的组织形式,文件分类:文本文件:ASCII文件,每个字节存放一个字符的ASCII码二进制文件:数据按其在内存中的存储形式原样存放返回如int型数100000010011100010000内存存储形式0010011100010000二进制形式0011000100110000001100000011000000110000ASCII形式文本文件特点:存储量大、速度慢、便于对字符操作二进制文件特点:存储量小、速度快、便于存放中间结果文件特点:文件处理方法缓冲文件系统:高级文件系统,系统自动为正在使用的文件开辟内存缓冲区非缓冲文件系统:低级文件系统,由用户在程序中为每个文件设定缓冲区输入文件缓冲区程序数据区输出磁盘输出文件缓冲区输入输出输入13.2文件类型指针文件结构体FILE缓冲文件系统为每个正使用的文件在内存开辟文件信息区文件信息用系统定义的名为FILE的结构体描述FILE定义在stdio.h中typedefstruct{int_fd;//文件号int_cleft;//缓冲区中剩下的字符数int_mode;//文件操作方式char*_next;//文件当前读写位置char*_buff;//文件缓冲区位置}FILE;返回指针变量说明:FILE*fp;用法:•文件打开时,系统自动建立文件结构体,并把指向它的指针返回来,程序通过这个指针获得文件信息,访问文件•文件关闭后,它的文件结构体被释放文件名文件使用方式文件类型指针C程序操作系统磁盘13.3文件的打开与关闭C文件操作用库函数实现,包含在stdio.h文件使用方式:打开文件--文件读/写--关闭文件系统自动打开和关闭三个标准文件:标准输入------键盘stdin标准输出------显示器stdout标准出错输出-----显示器stderr打开文件fopenFILE*fp;例:fp=fopen(“a1”,“r”);要打开的文件名使用文件方式返回“r+/rb+”(读写)“a/ab”(追加)“w/wb”(只写)“r/rb”(只读)“w+/wb+”(读写)“a+/ab+”(读写)为输入打开一个文本/二进制文件为输出打开或建立一个文本/二进制文件为读/写打开一个文本/二进制文件为读/写建立一个文本/二进制文件为读/写打开或建立一个文本/二进制文件向文本/二进制文件尾追加数据文件使用方式含义例文件打开与测试FILE*fp;fp=fopen(“aa.c”,“w”);if(fp==NULL){printf(“Fileopenerror!\n”);exit(0);}例FILE*fp;fp=fopen(“c:\\fengyi\\bkc\\test.txt”,“r”);例FILE*fp;char*filename=“c:\\fengyi\\bkc\\test.txt”fp=fopen(filename,“r”);文件关闭fclose作用:使文件指针变量与文件“脱钩”,释放文件结构体和文件指针fclose(fp)功能:关闭fp指向的文件返值:正常关闭为0;出错时,非0磁盘文件输出文件缓冲区输入文件缓冲区程序数据区a缓冲文件系统:fclose13.4文件的读写fputc函数与fgetc函数fputc•fputc(ch,fp);•功能:把一字节代码ch写入fp指向的文件中•返值:正常,返回ch;出错,为EOFfgetc•ch=fgetc(fp);•功能:从fp指向的文件中读取一字节代码•返值:正常,返回读到的代码值;读到文件尾或出错,为EOF文件I/O与终端I/O#defineputc(ch,fp)fputc(ch,fp)#definegetc(fp)fgetc(fp)#defineputchar(c)fputc(c,stdout)#definegetchar()fgetc(stdin)返回#includestdio.hmain(){FILE*fp;charch,*filename=“out.txt”;if((fp=fopen(filename,w))==NULL){printf(cannotopenfile\n);exit(0);}printf(Pleaseinputstring:);ch=getchar();while(ch!='#'){fputc(ch,fp);putchar(ch);ch=getchar();}fclose(fp);}例13.1从键盘输入字符,逐个存到磁盘文件中,直到输入‘#“为止#includestdio.hmain(){FILE*in,*out;charch,infile[10],outfile[10];scanf(%s,infile);scanf(%s,outfile);if((in=fopen(infile,r))==NULL){printf(Cannotopeninfile.\n);exit(0);}if((out=fopen(outfile,w))==NULL){printf(Cannotopenoutfile.\n);exit(0);}while(!feof(in))/*((ch=getc(in))!=EOF)*/fputc(fgetc(in),out);/*putc(ch,out);*/fclose(in);fclose(out);}例13.2将一个磁盘文件中的信息复制到另一个磁盘文件中。feoffeof(fp)功能:判断文件是否结束返值:文件结束,返回真(非0);文件未结束,返回0判断二进制文件是否结束while(!feof(fp)){c=fgetc(fp);……..}fread函数与fwrite函数fread(buffer,size,count,fp);fwrite(buffer,size,count,fp);功能:读/写数据块返值:成功,返回读/写的块数;出错或文件尾,返回0说明:•buffer:指向要输入/输出数据块的首地址的指针•size:每个要读/写的数据块的大小(字节数)•count:要读/写的数据块的个数•fp:要读/写的文件指针•fread与fwrite一般用于二进制文件的输入/输出#includestdio.h#defineSIZE4structstudent_type{charname[10];intnum;intage;charaddr[15];}stud[SIZE];main(){inti;for(i=0;iSIZE;i++)scanf(%s%d%d%s,stud[i].name,&stud[i].num,&stud[i].age,stud[i].addr);save();}voidsave(){FILE*fp;inti;if((fp=fopen(d:\\fengyi\\exe\\studat.txt,wb))==NULL){printf(cannotopenfile\n);return;}for(i=0;iSIZE;i++)if(fwrite(&stud[i],sizeof(structstudent_type),1,fp)!=1)printf(filewriteerror\n);fclose(fp);}voiddisplay(){FILE*fp;inti;if((fp=fopen(d:\\fengyi\\exe\\studat.txt,rb))==NULL){printf(cannotopenfile\n);return;}for(i=0;iSIZE;i++){fread(&stud[i],sizeof(structstudent_type),1,fp);printf(%-10s%4d%4d%-15s\n,stud[i].name,stud[i].num,stud[i].age,stud[i].addr);}fclose(fp);}例13.3从键盘输入4个学生数据,把他们转存到磁盘文件中fprintf函数与fscanf函数fprintf(文件指针,格式字符串,输出表列);fscanf(文件指针,格式字符串,输入表列);功能:按格式对文件进行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其他读写函数getw与putw函数:对磁盘文件读写一个字(整数)fgets与fputs:读写字符串•fgets(str,n,fp);•fputs(“China”,fp);fputs把s指向的字符串写入fp指向的文件fgets从fp所指文件读n-1个字符送入str指向的内存区,并在最后加一个‘\0’(若读入n-1个字符前遇换行符或文件尾(EOF)即结束)13.5文件的定位几个概念文件位置指针-----指向当前读写位置的指针读写方式•顺序读写:位置指针按字节位置顺序移动•随机读写:位置指针按需要移动到任意位置rewind函数Rewind函数rewind(fp);•功能:重置文件位置指针到文件开头•返值:无返回例13.4有一个磁盘文件,第一次将它的内容显示在屏幕上,第二次把它复制到另一文件上。#includestdio.hmain(){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);}fseek函数fseek(文件类型指针,位移量,起始点)功能:改变文件位置指针的位置返值:成功,返回0;失败,返回非0值位移量(以起始点为基点,移动的字节数)0向后移动0向前移动例13.5磁盘文件上有10个学生数据,要求读入第1、3、5、7、9个学生数据并显示#includestdio.hStructstudent_type{charname[10];intnum;intage;charsex;}stud[10];main(){intI;FILE*fp;if((fp=fopen(“stud.dat,rb))==NULL){printf(“cannotopenfile\n);exit(0);}for(i=0;i10;i+=2){fseek(fp,sizeof(structstudent_type),0);fread(&stud[i],sizeof(structstudent_type,1,fp)printf(“%s%d%d%c\n,stud[i].name,stud[i].num,stud[i].age,stud[i].sex);}fclose(fp);}ftell函数ftell(fp);功能:返回位置指针当前位置(用相对文件开头的位移量表示)返值:成功,返回当前位置指针位置;失败,返回-1L,13.6出错的检测ferror函数ferror(fp);功能:测试文件是否出现错误返值:未出错,0;出错,非0说明•每次调用文件输入输出函数,均产生一个新的