第9章 文件(课件)-《 C语言程序设计》同步教学(电子工业出版社)

2024-08-10
| 39页
| 83人阅读
| 12人下载
普通

内容正文:

第9章 文件 9.1 文件类型指针 9.2 文件的打开与关闭 9.3 文件的读写操作 9.4 文件定位与出错检测 9.5 其他文件函数 文件是存储在外部介质上数据的集合,是程序设计中一个重要的概念。操作系统以文件为单位对数据进行管理,也就是说,如果想找存储在外部介质上的数据,必须先按文件名找到所指定的文件,然后再从该文件中读取数据。要向外部介质上存储数据也必须先建立一个文件(以文件名为标识),才能向它输出数据。 9.1 文件类型指针 文件结构指针是一个指向文件有关信息的指针。这些信息定义了文件的文件名、状态和当前位置。在概念上文件结构指针标志着一个指定的磁盘文件。与文件结构指针组合的“流”用来告诉系统的每个缓冲型I/O函数应该到什么地方去完成操作。 文件结构指针是一个FILE型指针变量。FILE结构是在头文件<stdio.h>中定义的,因此对文件操作的程序,在最前面都应写上文件包含命令: #include < stdio.h >。 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结构体类型在头文件stdio.h中定义如下: 例如定义一个文件型指针变量: FILE *fp; 说明: fp就是一个指向FILE类型结构的指针变量,通过该文件指针变量就可以找到它相关联的文件,从而对文件进行读写操作。 9.2 文件的打开与关闭 在C语言程序中使用文件,需要完成以下工作: (1)声明一个FILE类型的文件指针变量。 (2)通过调用fopen( )函数打开文件。 (3)调用适当的文件操作函数完成必要的I/O操作。 (4)通过调用fclose( )函数关闭文件。 简单说来,对磁盘文件的操作是 先打开,再读写,后关闭。 fopen( )函数打开一个流并把一个文件与这个流连接。fopen( )函数的调用形式为: FILE * fp; fp=fopen(filename,mode); 例:fp=fopen(“test.txt”,“w”) 其中: filename必须是一个字符串组成的有效文件名; mode是说明文件打开方式的字符串,在Dev-C++中,有效的 mode值如下表所示; fopen( ) 函数如果成功地打开所指定的文件,则返回指向新打开文件的指针,且假定的文件位置指针指向文件首部;如果未能打开文件,则返回一个空指针。 1.fopen( )函数 文件操作方式 含 义 指定文件不存在时 指定文件存在时 “r”只读 打开一个文本文件只读 出错 正常打开 “w”只写 生成一个文本文件只写 建立新文件 原文件内容丢失 “a”追加 对一个文本文件添加 建立新文件 原文件尾部追加数据 “rb” 打开一个二进制文件只读 出错 正常打开 “wb” 生成一个二进制文件只写 建立新文件 原文件内容丢失 “ab” 对一个二进制文件添加 建立新文件 原文件尾部追加数据 “r+” 打开一个文本文件读/写 出错 正常打开 “w+” 生成一个文本文件读/写 建立新文件 原文件内容丢失 “a+” 打开或生成一个文本文件读/写 建立新文件 原文件尾部追加数据 “rb+” 打开一个二进制文件读/写 出错 正常打开 “wb+” 生成一个二进制文件读/写 建立新文件 原文件内容丢失 ab+” 打开或生成一个二进制文件读/写 建立新文件 原文件尾部追加数据 #include <stdio.h> #include <stdlib.h> int main() { FILE *fp; if ((fp=fopen("test.txt","w"))==NULL) { puts(“不能打开此文件 ”); exit(1); } return 0; } 说明: 在写文件之前先检验已打开的文件是否有错,如写保护或磁盘已写满等。上例中用了NULL,也就是0,因为没有文件指针会等于0。NULL是stdio.h 中定义的一个宏。 【例9.1】打开一个名为 test.txt 文件并准备写操作。 说明: 在打开一个文件作为读操作时,该文件必须存在;如果文件不存在,则返回一个出错信息。 以读操作“r”或“rb”方式打开一个文件,只能对该文件进行读出而不能对该文件进行写入。 用“w”或“wb”打开一个文件准备写操作时,如果该文件存在的话,则文件中原有的内容将被全部抹掉,并开始存放新内容;如果文件不存在,则建立这个文件。以写操作“w”或“wb”方式打开一个文件,只能对该文件进行写入而不能对该文件进行读出。 在“a”、 “ab”、 “a+”、 “ab+”方式打开一个文件,要在文件的尾部再加写些内容,则在打开文件时,如果该文件存在,则文件中原有的内容不会被抹掉,文件位置指针指向文件末尾;如果该文件不存在,就建立这个文件。 以“r+”或“rb+”方式打开一个文件进行读写操作时,该文件必须存在,如果文件不存在,则返回一个出错信息。 以“w+”或“wb+”方式打开一个文件进行读写操作时,如果该文件存在,则文件中原有的内容将被抹掉;如果该文件不存在,就建立这个文件。 fclose()函数用来关闭一个已由fopen()函数打开的流。 fclose()函数的调用形式为: fclose(fp); 其中: fp 是一个调用 fopen()时返回的文件指针。 若关闭文件成功,则fclose()函数返回值为0;若fclose()函数的返回值不为0,则说明出错。 2.fclose()函数 9.3 文件的读写操作 读文件:从磁盘文件中将数据先读入内存。 外存(文件)-->内存 写文件:先将数据从内存读出,写入文件中。 内存-->外存(文件) (1) fputc()函数的调用形式为: fputc(ch,fp); 功能:用来向一个已由fopen( )函数打开的写操作流中写一个字符。 若fputc()操作成功,则返回值是输出的字符;若操作失败,则返回EOF(文件结束)。 为了书写方便,在stdio.h已经定义了一个宏putc(): #define putc (ch,fp) fputc(ch,fp) 说明:putc() 与 fputc()可以作为相同的函数对待。 1.fputc() 函数、fgetc() 函数和feof()函数 (2) fgetc()函数的调用形式为: fgetc(fp); 功能: fgetc()函数用来从一个已由fopen()函数打开的读操作流中读取一个字符。 fgetc()返回文件指针所指文件中当前位置上字符。当读到文件尾时,fgetc()返回一个EOF文件结束标记。 为了书写方便,在stdio.h已经定义了一个宏getc(): #define getc (fp) fgetc(fp) 说明:getc() 与 fgetc()可以作为相同的函数对待。 【例9.2】下面的程序段可以从文件头一直读到文件尾。 #include <stdio.h> int main() { FILE *fp; char ch; fp=fopen("test.txt","r"); ch=fgetc(fp); while(ch!=EOF){ printf("%c",ch); ch=fgetc(fp); } return 0; } 说明: 这只适用于读文本文件,不能用于读二进制文件。 (3) feof ()函数的调用形式为: feof(fp); 功能: feof()函数是文件结束检测函数,可以判断在读二进制数据时文件是否真的结束。 feof()函数将返回一个整型值,在到达文件结束点时其值为1,未达到文件结束点时其值为0。 下面的语句可以从二进制文件首一直读到文件尾。 #include <stdio.h> int main() { FILE *fp; char ch; fp=fopen("test.txt","r"); while(!feof(fp)) { ch=getc(fp); printf("%c",ch); } return 0; } 说明: 这一语句对文本文件同样适用,即对任何类型文件都有效,所以建议使用本函数来判断文件是否结束。 int main(){ FILE *in,*out; char infile[10]="d:\\a.txt",outfile[10]="d:\\b.txt",c; if((in=fopen(infile,"r"))==NULL){ printf("文件打不开"); exit(0); } if((out=fopen(outfile,"w"))==NULL){ printf("文件打不开"); exit(0); } while(!feof(in)) { c=fgetc(in); fputc(c,out); } fclose(in); fclose(out); return 0; } 【例9.3】将一个磁盘文件中的信息复制到另一个磁盘文件中,实现文件的拷贝功能。 fgets()函数和 fputs()函数用于从磁盘文件中读或写一个整型数据(一个字)。 用法与getc()函数和putc()函数完全相同,所不同的只是读写整形数据而不是字符。 【例9.4】下面的语句用来向文件指针fp所指的磁盘文件中当前位置上写一个整型数据。 putw(100,fp); 2.getw()函数和putw()函数 fgets()函数和 fputs()函数用来读写字符串的。 调用形式为: fgets(str,length,fp); 和 fputs(str, fp); 其中: str是一个字符指针或数组名;length是一个整数。函数fgets从fp指定文件的当前位置上读取字符串,直至读到换行符或第length-1个字符或遇到EOF为止。 3.fgets() 函数和fputs()函数 【例9.5】从指定文件读入一个字符串。 fgets(str,100,fp); 向指定的文件输出一个字符串。 fputs("guan-zhi@163.com",fp); fread()函数 和fwrite()函数是用来读写数据块的函数。 调用形式为: fread(buffer,size,count,fp); fwrite(buffer,size,count,fp); 其中: buffer:是一个指针,在fread函数中,它表示存放输入数据的首地址。在fwrite函数中,它表示存放输出数据的首地址。 size:表示数据块的字节数。 count:表示要读写的数据块块数。 fp: 表示文件指针。 4.fread() 函数和fwrite() 函数 fread()函数操作成功时,返回实际读取的字段个数count;到达文件尾或出现错误时,返回值小于count。fwrite()函数操作成功时,返回实际所写的字段个数count;返回值小于count,说明发生了错误。 【例9.6】如果文件以二进制文件方式打开,可以用fread()和fwrite()读写任何类型信息。 fread(f,4,2,fp); 表示:从fp所指向的文件中读取2个4个字节的数据,存储到数组f中。 或 fwrite(f,4,2,fp); 表示:从数组f所指的数据(2个4字节)写入fp所指的文件。 例如: #include <stdio.h> main() { FILE *fp; int i,a[10]={1,2,3,4,5,100,100,100,100,100}; fp=fopen("d2.dat", "wb"); fwrite(a,sizeof(int),5,fp); fwrite(a,sizeof(int),5,fp); fclose(fp); fp=fopen("d2.dat", "rb"); fread(a,sizeof(int),10,fp); fclose(fp); for(i=0;i<10;i++) printf("%d",a[i]); } 思考: a改为a+5呢? 这两个函数功能是与printf()和scanf()完全相同,但其操作对象是磁盘文件。 调用方式为: fprintf(fp,“控制字符串”,参数表); fscanf(fp,“控制字符串”,参数表); 其中: fp是一个有效的文件指针,控制字符串和参数表同printf()和scanf()函数。 fprintf()函数操作成功,返回实际被写的字符个数;不成功返回一个负数。 fscanf()函数操作成功,返回实际被赋值的参数个数;若返回EOF,则表示试图去读取超过文件末尾的部分。 5.fprintf() 函数和fscanf()函数 fprintf()函数操作成功,返回实际被写的字符个数;出现错误时,返回一个负数。fscanf()函数操作成功,返回实际被赋值的参数个数;若返回EOF,则表示试图去读取超过文件末尾的部分。 【例9.7】按格式实现文件fp与变量i、t之间的输出/输入操作。 fprintf(fp, "%d,%6.2f",i,t); 或 fscanf(fp, "%d,%f",&i,&t); 注意: 虽然fprintf()函数和fscanf()函数是向磁盘文件读写各种数据最容易的方法,但效率并不一定最高。因为它们以格式化的ASCII数据而不是二进制数据进行输入输出,与在屏幕上显示是相同的。如果要求速度快或文件很长时应使用fread()函数和 fwrite()函数。 例如: #include <stdio.h> int main() { FILE *fp; int k,n,a[6]={1,2,3,4,5,6}; fp=fopen("d2.dat","w"); fprintf(fp,"%d%d%d ",a[0],a[1],a[2]); fprintf(fp,"%d%d%d ",a[3],a[4],a[5]); fclose(fp); fp=fopen("d2.dat","r"); fscanf(fp,"%d%d",&k,&n); printf("%d %d ",k,n); fclose(fp); return 0; } 9.4 文件定位与出错检测 1、文件定位函数——fseek()函数 调用形式为: fseek(文件指针,位移量,起始点); 功能:fseek()函数可以完成随机读写操作,可以随机设置文件位置指针。 说明: fseek()函数操作成功,返回0,返回非零值表示失败。 “位移量”表示移动的字节数,要求位移量是long型数据,以便在文件长度大于64KB 时不会出错。当用常量表示位移量时,要求加后缀“L”。 “起始点”是下表中所示的几个宏名之一: 宏名字 数值表示 起始点 SEEK_SET 0 文件开始为起点 SEEK_CUR 1 文件当前位置为起点 SEEK_END 2 文件末尾为起点 以下是fseek函数调用的几个例子: fseek(fp,100L,0); 将位置指针移到离文件头100个字节处 fseek(fp,50L,1); 将位置指针移到离当前位置50个字节处 fseek(fp,-10L,2); 将位置指针从文件末尾处向后退10个字节。 ferror()函数用来确定文件操作中是否出错。 调用形式为: ferror(fp); 其中:fp是一个调用fopen()时返回的文件指针。若在文件操作中发生了错误,则ferror()函数返回一个非零值,即“真”;否则返回值为0,即“假”。 2、出错检测函数——ferror()函数 9.5 其他文件函数 1、rewind()函数 rewind()函数用来将文件位置指针重新设置到该文件首。 其调用形式是: rewind(fp); 其中fp是一个有效的文件指针,其定义如前所述。 此函数没有返回值,但使feof()函数的值置为0。 此函数等效于fseek(fp,0L,SEEK_SET); ftell()函数的作用是得到流式文件中位置指针的当前位置,用相对于文件开头的位移量来表示。 其调用形式是: ftell(fp); 其中fp是一个有效的文件指针,其定义如前所述。 2、ftell()函数 由于文件中的位置指针经常移动,人们往往不容易辨清其当前位置。用ftell()函数可以得到当前位置。如果ftell()函数返回值为-1L,表示出错。 例如: i=ftell(fp); if (i==-1L) printf("出错 "); 变量i存放当前位置,应当定义为长整型变量,如调用函数出错(如不存在这个文件),则输出“出错”信息。 clearerr()函数的作用是使文件错误标志和文件结束标志置为0。 其调用形式是: clearerr(fp); 其中fp是一个有效的文件指针,其定义如前所述。 3、clearerr()函数 假设在调用一个输入输出函数时出现错误,ferror()函数值为一个非零值。在调用clearerr(fp)后,ferror(fp)的值变成0。 只要出现错误标志,就一直保留,直到对同一文件调用clearerr()函数或rewind()函数,或任何其他一个输入输出函数为止。 remove( )函数的作用是删除所指定的文件。 其调用形式是: remove(filename); 字符串filename是指定要删除的文件名。该函数正确执行完毕返回0,否则返回非零值。 4、remove( )函数 本章小结 文件是程序设计中一种重要的数据类型,是存储在外部介质上的一组数据集合。C语言中文件根据数据组织形式有二进制文件和文本文件。 对文件操作分为三步:打开文件、读写文件、关闭文件。 文件的读写操作可以使用库函数fscanf() 与fprintf()函数、fgetc()与fputc()函数、fgets()与fputs()函数、fread()与fwrite()函数,这些函数最好配对使用,以免引起输入输出的混乱。 $$

资源预览图

第9章  文件(课件)-《 C语言程序设计》同步教学(电子工业出版社)
1
第9章  文件(课件)-《 C语言程序设计》同步教学(电子工业出版社)
2
第9章  文件(课件)-《 C语言程序设计》同步教学(电子工业出版社)
3
第9章  文件(课件)-《 C语言程序设计》同步教学(电子工业出版社)
4
第9章  文件(课件)-《 C语言程序设计》同步教学(电子工业出版社)
5
第9章  文件(课件)-《 C语言程序设计》同步教学(电子工业出版社)
6
所属专辑
由于学科网是一个信息分享及获取的平台,不确保部分用户上传资料的 来源及知识产权归属。如您发现相关资料侵犯您的合法权益,请联系学科网,我们核实后将及时进行处理。