版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
1、第11章文件的输入与输出,C语言程序设计,2,本章介绍文件概念及其相关术语、C语言输入输出的实现方法、流的概念和流式文件的输入和输出、文本文件的输入输出和二进制文件的输入输出、文件的顺序输入输出和文件的随机输入输出。 对输入输出的低层接口、文件在数据库和汉字显示方面的应用、流式文件库函数的设计也做了相应的介绍。,内容摘要,3,重点讲解,11.1文件概述 11.2FILE指针和标准流式文件 11.3流式文件的顺序输入输出 11.4流式文件的随机输入输出 11.5其它文件操作函数 11.6输入输出的低层接口 11.7流式文件系统中库函数的设计,小结,4,本章讨论关于计算机的存储器与I/O设备之间数
2、据交换的程序设计问题。,目录,问题背景,5,基于操作系统的软件系统是将一组应用相关的数据构成一个逻辑单位,存储在外部存储器之中的。这个逻辑单位被称为文件,以文件名加以标识。,目录,11.1文件概述,文件是指内存以外介质上以某种形式组织起来的数据集合。在C 语言中,文件中的数据分为两种数据格式存储。,6,第一类文本格式:将文件数据区的每个字节解释为一个字符,回车符n 解释为行结束标志(回车符之间的符号串称为一行)。,main() printf(“hi”); _,这种格式文件称为文本文件、行文文件、正文文件或纯文本文件。 文本文件是以字符序列形式存储数据的文件。,7,如果将内存数据按文本文件存储到
3、外存中,则 C 语言通常需要将内存数据按指定格式转换成字符形式。,例如,int x=128; 转换格式:“%d”,0000 0000 1000 0000,x,内存:,0011 0001 0011 0010 0111 0000,外存:,1,2,8,如果将存储在外存中的文本文件数据取回到内存,则C语言通常需要将按指定格式转换成内存数据形式。,例如,int x=128; 转换格式:“%d”,0000 0000 1000 0000,x,内存:,0011 0001 0011 0010 0111 0000,外存:,1,2,8,写文件,读文件,8,如果当将内存多个数据写入文本文件的时候,特别注意的是:在两个
4、数据之间增加必的间隔符。目的在于读文本文件时,能够保证获得数据转换的正确性。,例如,int x=128,y=821,a,b ; 转换格式:“dd”或“d d”,0000 0000 1000 0000,x,0000 0011 0011 0101,y,内存:,128821,9,C 语言是将键盘、显示器和打印机设备视同为文本文件进行处理的。对于输出设备显示器和打印机,遇到输出回车符时,便换行显示或打印。,在字符模式下,显示器和打印机逻辑上呈现文本特性。,10,第二类二进制格式:文件数据区仅按每个二进制位解释为0或1。这种格式的文件称为二进制文件。二进制文件是以二进制数字0/1序列形式存储数据的文件。
5、,如果将内存数据按二进制文件存储在外存中,则 C 语言不需要转换,直接按内存数据0/1形式存储。,如果将存储在外存中二进制文件的数据取回内存,则C 语言不需要转换,直接取回即可,其数值按内存单元之数据类型解释。,11,C语言对文件的读写提供有两种方式:顺序读写和随机读写。 无论那种读写方式,文件采用一个文件读写指针记录对于文件的当前读写位置,并在一次读写后自动向文件尾方向移动。,按文本格式 “c”转换读入1个char数据:00110001。,按文本格式 “d”转换读入1个int数据:00000000 00001100。,12,其移动距离取决于转换格式之对应字符串的长度。,12,按二进制格式读入
6、1个char数据:00110001。,按二进制读入1个int数据:00110001 00110010。,C语言对文件的读写提供有两种方式:顺序读写和随机读写。 无论那种读写方式,文件采用一个文件读写指针记录对于文件的当前读写位置,并在一次读写后自动向文件尾方向移动。,12594,其移动距离取决于内存单元之数据类型的长度。,13,顺序读写方式:打开文件时文件读写指针指向文件头或文件尾,读写一个 “数据” 后,读写指针自动指向下一个 “数据” 或文件尾。程序无法修改文件读写指针,文件指针始终往文件尾方向移动。,数据的划分取决于读写方式和转换格式!,随机读写方式:以二进制格式打开文件时,文件读写指针
7、指向文件头或文件尾,读写一个“数据”后读写指针自动指向下一个“数据”或文件尾。程序可以修改文件读写指针,文件指针可在头尾两个方向往返移动。,14,标准I/O函数是基于I/O流的操作。流是从源点到终点方向流动的数据。文件是“存储”在I/O设备上的数据的抽象;流是内存与I/O设备之间流动的数据的抽象。实现时,流存储在I/O缓冲区中。,实现C语言应用程序的I/O运算之两种方法:,标准I/O函数是基于I/O流的操作。 C 语言实现“字符流和BIT流特性差异的I/O设备”之间的转换,即各种I/O设备的差异对于应用程序是透明的。基于I/O流操作的文件称为流式文件。,15,11.2FILE指针和标准流式文件
8、,目录,FILE是C语言标准中定义的一种结构类型名称。 FILE类型的结构变量记载关于流的控制方面的全部信息。 不同的 C编译器关于FILE结构类型的定义会略有差异,但提供的库函数原型都是满足C语言标准。,16,_streams是在头文件stdio.h中定义的、由系统创建、赋值和更新FILE类型的数组变量,其数组元素个数是由系统宏定义的、可同时打开的文件数目。,#define OPEN_MAX 20 extern FILE _Cdecl _streams;,_streams,FILE * fp;,程序中仅使用FILE * 型变量,通常简称为FILE指针。,fp=fopen(, ); /*fop
9、en()打开文件函数*/,fclose(fp); /*fclose()关闭文件函数*/,文件IO操作步骤,17,_streams,#define stdin ( fp=fopen(“c:test.dat”,”w”);,11.3.1 文件的打开与关闭,19,可以选择的文件打开方式mode如下。其中,r表示只读,w表示只写,a表示添加,+表示更新,b表示二进制文件。 如果文件打开方式中不含有 “b” ,则表示以文本格式打开。创建文件时,如果创建文件已经存在,则内容被清空。,r 以只读方式文本格式打开 w 以只写方式文本格式打开或创建 a 以尾部添加只写方式文本格式打开或创建 rb 以只读方式二进制
10、格式打开 wb 以只写方式二进制格式打开或创建 ab 以尾部添加只写方式二进制格式打开或创建 r+ 以更新(读写)方式文本格式打开 w+ 以更新(读写)方式文本格式打开或创建 a+ 以尾部添加、更新方式文本格式打开或创建 r+b 或 rb+ 以更新(读写)方式二进制格式打开 w+b 或 wb+ 以更新(读写)方式二进制格式打开或创建 a+b 或 ab+ 以尾部添加、更新方式文本格式打开或创建,20,文件关闭函数fclose()声明如下,功能是关闭stream文件指针 “指向”的文件,返回值0表示正确执行,EOF表示出错。 int _Cdecl fclose(FILE *stream);,文件I
11、O操作步骤,例如,按文本格式、顺序写方式打开文件c:test.dat,之后关闭该文件。 FILE * fp; fp=fopen(“c:test.dat”,”w”); fclose(fp);,21,例11.3 文件打开、关闭、以及读写操作举例。文件以文本文件格式创建,以二进制文件的形式读取,目的是观察文本文件在磁盘中的存储方式。,#include stdio.h void main(void) char a20; unsigned char u,i=0; FILE *fin,*fout; fout=fopen(c:abc.dat,w+); while(gets(a)!=NULL) fprintf
12、(fout,%s,a); fclose(fout); fin=fopen(c:abc.dat,r+b); while(!feof(fin) fread( ,文件IO操作步骤,22,11.3.2 文件的重定向,文件的重定向函数freopen()声明如下,功能是在关闭fp指向的文件之后,fp重指向按照mode方式打开的、filename指定的文件,函数返回新打开的文件指针。如果失败返回NULL。,FILE * _Cdecl refopen(const char * filename, const char * mode,FILE *fp);,例如,按文本格式、顺序写方式打开文件c:test.dat
13、。 FILE * fp; fp=fopen(“c:oldfile”,”r”); refopen(“c:newfile”,”w”,fp);,23,void main(int argc, char* argv) int ch; if(argc!=3)printf(Arguments error!n);exit(-1); if(freopen(argv1,r,stdin)=NULL) /* stdin指向source_file */ printf(Cant open %s file!n,argv1);exit(-1); freopen(argv2,w,stdout); /* stdout指向targ
14、et_file */ while(ch=getchar()!=EOF) /* 从source_file中读字符 */ putchar(ch); /* 向target_file中写字符,实现拷贝复制 */ fclose(stdin); /* 关闭source_file */ fclose(stdout); /* 关闭target_file */ ,提示:包括标准文件在内的任意打开的文件都可以重定向。,24,11.3.3 基于字符的文件读/写,int fgetc(FILE *stream); int fputc(int c, FILE *stream); int fgetchar(void); i
15、nt fputchar(int c); int _fgetc(FILE *stream); /* 仅供宏getc()使用 */ int _fputc(char c, FILE *stream); /* 仅供宏 putc()使用 */ int ungetc(int c, FILE *stream);,C 提供的基于字符的IO函数原型如下,其声明在 stdio.h 中。即使用时,必须先用#include 或#include stdio.h。,这些标准IO函数是对标准文件或以文本格式打开的文件进行操作的!,25,int fgetc(FILE *stream)函数,从文件指针 stream 指向的文件
16、中读取一个字符,并将该字符作为unsigned char类型转换为整型值返回。遇到文件尾或读操作出错时返回EOF。,26,int _fgetc(FILE *stream)函数、,int _fputc(FILE *stream)函数,函数_fgetc和_fputc通常是供宏定义中使用的。,#define getchar() getc(stdin) #define putchar(c) putc(c), stdout) #define getc(f) (-(f)-level) = 0) ? (unsigned char)(+(f)-curp)-1 : _fgetc (f) #define putc
17、(c,f) (+(f)-level) curp)-1=(c) :_fputc (c),f),int ungetc(int c, FILE *stream)函数,将参数c之低字节作为字符回送stream流中并作为函数值返回。如果失败返回EOF。,27,11.3.4 基于字符串的文件读/写,C 提供的基于字符串的IO函数原型如下,其声明在stdio.h之中。即使用时,必须先用#include 或#include stdio.h。,char * gets(char *s); int puts(const char *s); char * fgets(char *s, int n, FILE *str
18、eam); int fputs(const char *s, FILE *stream);,这些标准IO函数是对标准文件或以文本格式打开的文件进行操作的!,调用标准C 提供的字符串输入输出函数每次从输入文件中读或者向输出文件写一个字符串。,28,char * gets(char *s)函数,从标准输入流stdin中读一行字符,存入字符指针 s 指向的内存单元,行尾部的换行符n被替换成0,返回值是指向输入字符串的指针s。如果遇到文件尾或出错,返回NULL。,char * puts(const char *s)函数,将指针 s 指向的字符串写入标准输出流stdout,并在行尾添加换行符n,函数返回
19、一个非负值。如果出错返回EOF。,char * fgets(char *s, int n, FILE *stream)函数,从stream指向的流中读一行(输入行长度n时),或至多读n-1个字符(行长度n时),存入到s指向的内存单元,返回输入字符串的指针s。如果出错或遇文件尾返回NULL。,char * fputs(const char *s, FILE *stream)函数,将指针s 指向的字符串写入stream指向的流中,函数返回一个非负值。如果出错返回EOF。,29,11.3.5 文件的格式读/写,C 提供的格式读写的IO函数原型如下,其声明在stdio.h中。即使用时,必须先用#inc
20、lude 或#include stdio.h。,int printf(const char *format, .); int scanf(const char *format, .); int fprintf(FILE *stream, const char *format, .); int fscanf(FILE *stream, const char *format, .); int sprintf(char *buffer, const char *format, .); int sscanf(const char *buffer, const char *format, .);,这些标
21、准IO函数是对标准文件或以文本格式打开的文件进行操作的!,后面4个函数功能和使用方法,与第3章的printf函数和scanf函数相同或类似,差异在于输入输出文件不同。 输出函数正常时都返回输出字符个数,写操作出错时返回负值。输入函数时都返回已输入项数,如果读操作出错都返回EOF。,30,11.3.6 文件的直接读/写,C 提供的直接读写的IO函数原型如下,其声明在stdio.h中。即使用时,必须先用#include 或#include stdio.h。,size_t fread(void *ptr, size_t size, size_t n, FILE *stream); size_t fw
22、rite(const void *ptr, size_t size, size_t n,FILE *stream);,这些标准IO函数是对标准文件或以文本格式打开的文件进行操作的!,文件直接输入输出,又称为文件成组输入输出。它指通过一次I/O能够完成若干条记录(record)的输入或输出。 记录是一个十分宽泛的概念。通常,记录是指由若干个字段组成的数据集。在 C 语言中可以采用结构数据类型表示,结构的成员对应于记录的字段。 fread和fwrite函数也适用于二进制形式文件的读写。,31,size_t fread(void *ptr, size_t size, size_t n, FILE *
23、stream)函数,从stream指向的输入文件中读取至多n个大小为size的记录,存入到指针ptr指向的内存单元中,返回值是实际读取记录数。,size_t fwrite(const void *ptr, size_t size, size_t n,FILE *stream)函数,从指针ptr指向的内存缓冲区中取n个大小为size的记录,写到指针stream指向的输出文件中,返回值是写出的记录数。 当返回值小于n时,表示写操作出错。,文件尾测试函数feof(),如遇到文件尾,返回非0值,否则返回0。 出错测试函数ferror(),如果出错,返回非0值,否则返回0。,重要提示:实际上,不论文件是
24、按文本格式,还是二进制格式打开,函数fread和fwrite的读写都是指定的字节数(=sizen),直接进行读写操作的,不做任何转换。即函数fread和fwrite的读写是二进制位流。,32,例如,下面程序给出了函数fwrite和fread基本用法和WEN文件IO操作效果。(A的ACSII码:0 x41),i,j,a,b,test.txt,¥,A B,33,11.4流式文件的随机输入输出,11.4.1 文件定位函数,目录,C 提供的文件定位函数原型如下,其声明在stdio.h中。即使用时,必须先用#include 或#include stdio.h。,流式文件的随机输入输出是指对文件的读写可以
25、从文件内指定的位置进行,而不必每次从头顺序开始。,int fseek(FILE *stream, long offset, int origin); long ftell(FILE *stream); int fgetpos(FILE *stream, fpos_t *pos); int fsetpos(FILE *stream, const fpos_t *pos); void rewind(FILE *stream);,对二进制格式文件和文本格式文件,均可使用定位函数。,34,int fseek(FILE *stream, long offset, int origin)函数,将strea
26、m指向的文件之当前读写指针,定位到origin+offset。如果正常定位,fseek函数返回0,否则返回非0值。,origin和offset分别称为基准点和偏移量。,基准点有三种取值:SEEK_SET、SEEK_CUR和SEEK_END。 #define SEEK_SET 0 文件起始位置为基准点 #define SEEK_CUR 1 文件当前位置为基准点 #define SEEK_END 2 文件尾部位置为基准点,C 标准:对二进制格式文件,基准点的取值与偏移量无关;对文本格式文件基准点只能取 0 ,而偏移量可以取 0 或ftell函数的返回值。,35,long ftell(FILE *s
27、tream)函数,读取文件读写指针的当前值返回,出错时返回-1L。,int fgetpos(FILE *stream, fpos_t *pos)函数,将stream指向文件的读写指针当前值,保存到 pos 指针所指的 fpos_t类型的对象中。成功保存,函数返回0,否则返回非0值。,int fsetpos(FILE *stream, const fpos_t *pos)函数,用fgetpos函数获得的pos指针所指对象中的值,设置stream所指向文件的当前位置。设置成功函数返回0,否则返回非0值。,void rewind(FILE *stream)函数,将文件指针 stream 指向文件的读
28、写指针,重新定位到文件的起始位置,清除文件结束标志和出错标志。,文件test.dat之数据区,36,11.4.2 文件随机读/写,利用各种文件的定位函数和文件的读写函数,可以实现任何文件的随机读写。,通常,将大量数据储存在文件中,应该首先设计数据存储格式。之后,按照设计的数据存储格式,设计应用程序,确保对文件进行正确的文件指针定位和读写操作。 换言之,数据是什么规律写入文件的,通常应该按此规律定位和读出存储在文件之中的数据。 定位函数中参数值,依赖于具体的编译程序之约定。在软件开发时,需要认真阅读所使用的开发工具的相关技术资料!,37,11.5其它文件操作函数,11.5.1 文件访问类函数,目
29、录,C标准规定了五个文件访问类操作函数如下。其中,前2个函数已经讨论过,剩余3个函数都是关于缓冲区的操作。,FILE * _Cdecl fopen(const char * filename, const char * mode); int _Cdecl fclose(FILE *stream); int fflush(FILE *stream); int setvbuf(FILE *stream, char *buf, int mode, size_t size); void setbuf(FILE *stream, char *buf);,38,int setvbuf(FILE *stre
30、am, char *buf, int mode, size_t size)函数,在打开文件之后,其他任何有关文件的操作执行之前,setvbuf函数被调用:setvbuf函数用buf指向的存储区,作为stream指向流的缓冲,缓冲方式由参数mode决定,缓冲大小由参数size决定。调用成功函数返回0,否则返回非0值。,void setbuf(FILE *stream, char *buf)函数,功能上与 setvbuf函数一样。不同的是该函数采用_IOFBF全缓冲,缓冲大小用BUFSIZ,函数没有返回值。 缓冲大小值BUFSIZ,在stdio.h定义,一般为512个字节。,将stream指向的输
31、出缓冲区或更新缓冲区(用追加方式打开)中尚未存盘的数据强制性的全部写到介质文件中。如果stream为NULL,执行fflush操作将使所有缓冲区的数据存盘。写操作成功函数返回0,否则置出错标志并返回EOF。,int fflush(FILE *stream)函数,39,11.5.2 文件操作类函数,C标准规定了四个文件操作类函数,在stdio.h头文件中声明的函数原型如下。,int remove(const char * filename); int rename(const char * oldname, const char * newname); FILE * tmpfile(void);
32、 char * tmpnam(char *s);,实际上,remove函数就是DOS的del操作之功能。,int remove(const char * filename)函数,文件删除函数:删除以参数filename指向的字符串为文件名的文件。如果操作成功,remove函数返回0,否则返回非0值。 如果参数filename指向的文件已经打开,remove操作之处理方式由C编译器自行决定。,40,int rename(const char * oldname, const char * newname)函数,文件换名函数:以参数 oldname 指向的字符串为旧文件名,更换成以参数newnam
33、e指向的字符串为新文件名。如果操作成功,函数返回0,否则返回非0值。,实际上,rename函数就是DOS的ren操作之功能。,FILE * tmpfile(void)函数,以“wb+”方式创建一个临时二进制文件,该临时文件在文件关闭或程序结束时被自动清除。如果调用成功,函数返回一个指向创建的临时文件之文件指针,否则返回NULL。,char * tmpnam(char *s)函数,产生一个在操作系统的文件系统之下、与已存在的文件不相同的文件名,存入参数s指针指向的字符数组。如果操作成功,返回参数s的值,否则返回NULL。,41,11.5.3 出错检测类函数,C标准规定了四个文件检错类函数,在st
34、dio.h头文件中声明的函数原型如下。,void clearerr(FILE *stream); int feof(FILE *stream); int ferror(FILE *stream); void perror(const char *s);,typedef struct short level; /* 缓冲区空满 */ unsigned flags; /* 文件状态标志 */ char fd; /* 文件描述符 */ unsigned char hold; /* 非缓冲回送字符 */ short bsize; /* 缓冲区大小 */ unsigned char * buffer;
35、/* 指向缓冲区指针 */ unsigned char * curp; /* 当前读写位置指针*/ unsigned istemp; /* 临时文件描述符 */ short token; /* 有效性检验标志 */ FILE; /* 结构类型命名 */,42,void clearerr(FILE *stream)函数,清除stream所指流的EOF标志和出错标志,函数无返回值。,int feof(FILE *stream)函数,检测stream所指流是否到达尾。如果到达,函数返回非0值,否则返回0值。,int ferror(FILE *stream)函数,检测stream所指流的出错,如果出错
36、,函数返回非0值,否则返回0值。,void perror(const char *s)函数,将出错信息(全局变量errno的值)写入字符指针s所指的字符数组中,无返回值。,43,11.6输入输出的低层接口,目录,与流式文件使用标准C 定义的基于缓冲的函数不同,输入输出的低层接口中使用的函数不是由标准C 定义,而是通过操作系统提供的功能调用(也称为接口)实现。 流式文件使用通过FILE结构定义的缓冲,而输入输出的低层接口不使用FILE文件指针,所使用的是整型文件说明符。 对于不同的操作系统,编译器提供的低层接口形式是统一的。差异之处在于对读写方式、文件属性的规定和符号常量的定义不尽相同不同。 在io.h中给出了C语言提供的底层接口函数原型的声明。,44,11.6.1 文件的顺序
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 2026中建港航局集团有限公司春季校园招聘笔试参考题库及答案解析
- 2026年3月广西百色市田阳区城镇公益性岗位招聘3人笔试模拟试题及答案解析
- 土工试验技术方案
- 2026河北新质科技有限公司校园招聘4人笔试参考题库及答案解析
- 东营经济技术开发区某公立幼儿园公开招聘1名劳务派遣教师笔试备考题库及答案解析
- 水质监测实验室废水处理方案
- 建筑工程进度计划编制培训
- 2026年宠物智能宠物保险行业分析报告
- 2026年甘肃定西岷县锁龙乡卫生院招聘乡村医生考试备考题库及答案解析
- 施工现场人员流动登记方案
- 防高坠安全教育课件
- 租赁合同范本及注意事项详解
- 印刷厂安全教育培训计划
- 水电站申请书
- 修井作业安全培训课件
- 具身智能+军事应用智能侦察机器人可行性研究报告
- 2025年中央纪委机关公开遴选公务员面试题深度解析与预测趋势
- 湖南省衡阳市一中2026届高三第一次月考数学试卷(含答案)
- 灰土地基施工课件
- 基于SLP法的京东物流园3C类仓库布局优化研究
- 2025年高等教育工学类自考-02200现代设计方法历年参考题库含答案解析(5套典型考题)
评论
0/150
提交评论