C语言程序设计基础与实训教程_第1页
C语言程序设计基础与实训教程_第2页
C语言程序设计基础与实训教程_第3页
C语言程序设计基础与实训教程_第4页
C语言程序设计基础与实训教程_第5页
已阅读5页,还剩37页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

1、在线教务辅导网: :/教材其余课件及动画素材请查阅在线教务辅导网QQ:349134187 或者直接输入下面地址:第11章 文 件主要内容C文件概述文件类型指针文件的翻开和关闭文件的读写文件的定位出错的检测文件输入输出小结11.1 C文件概述文件file是程序设计中一个重要的概念。所谓“文件一般指存储在外部介质上数据的集合。一批数据是以文件的形式存放在外部介质如磁盘上的。操作系统是以文件为单位对数据进行管理的,也就是说,如果想找存在于外部介质上的数据,必须先按文件名找到所指定的文件,然后再从该文件中读取数据。要向外部介质上存储数据也必须先建立一个文件以文件名标识,才能向它输出数据。11.1 C文

2、件概述以前各章中所用到的输入和输出,都是以终端键盘输入数据,运行结果输出到终端上。从操作系统的角度看,每一个与主机相连的输入输出设备都看作是一个文件。例如,终端键盘是输入文件,显示屏和打印机是输出文件。在程序运行时,常常需要将一些数据运行的最终结果或中间数据输出到磁盘上存放起来,以后需要时再从磁盘中输入到计算机内存。这就是要用到磁盘文件。11.1 C文件概述C语言把文件看作是一个字符字节的序列,即由一个一个字符字节的数据顺序组成。根据数据的组织形式,可分为ASCII文件和二进制文件。ASCII文件又称文本text文件,它的每一个字节放一个ASCII代码,代表一个字符。二进制文件是把内存中的数据

3、按其在内存中的存储形式原样输出到磁盘上存放。如果有一个整数10000,在内存中占2个字节,如果按ASCII码形式输出,那么占5个字节,而按二进制形式输出,在磁盘上只占2个字节,如图11-1所示。用ASCII码形式输出与字符一一对应,一个字节代表一个字符,因而便于对字符进行逐个处理,也便于输出字符。但一般占存储空间较多,而且要花费转换时间二进制形式与ASCII码间的转换。用二进制形式输出数值,可以节省外存空间和转换时间,但一个字节并不对应一个字符,不能直接输出字符形式。一般中间结果数据需要暂时保存在外存上以后又需要输入到内存的,常用二进制文件保存。11.2 文件类型指针缓冲文件系统中,关键的概念

4、是“文件指针。每个被使用的文件都在内存中开辟一个区,用来存放文件的有关信息如文件的名字、文件状态及文件当前位置等。这些信息是保存在一个结构体变量中的。该结构体类型是由系统定义的,取名为FILE。Turbo C在文件中有以下的文件类型声明。11.2 文件类型指针typedef structshort level; /*缓冲区“满或“空的程度*/ unsigned flags; /*文件状态标志*/ char fd; /*文件描述符*/ unsigned char hold; /*如无缓冲区不读取字符*/ short bsize; /*缓冲区的大小*/ unsigned char *buffer;

5、 /*数据缓冲区的位置*/ unsigned ar *curp; /*指针,当前的指向*/ unsigned istemp; /*临时文件,指示器*/ short token; /*用于有效性检查*/FILE;11.2 文件类型指针有了结构体FILE类型之后,可以用它来定义假设干个FILE类型的变量,以便存放假设干个文件的信息。例如,可以定义以下FILE类型的数组。FILE f5;定义了一个结构体数组f,它有5个元素,可以用来存放5个文件的信息。可以定义文件型指针变量,如:FILE *fp;11.2 文件类型指针fp是一个指向FILE类型结构体的指针变量。可以使fp指向某一个文件的结构体变量,

6、从而通过该结构体变量中的文件信息能够访问该文件。也就是说,通过文件指针变量能够找到与它相关的文件。如果有n个文件,一般应设n个指针变量指向FILE类型结构体的指针变量,使它们分别指向n个文件确切地说指向存放该文件信息的结构体变量,以实现对文件的访问。11.3 文件的翻开和关闭文件的翻开fopen函数文件的关闭fclose函数11.3.1 文件的翻开fopen函数ANSI C规定了标准输入输出函数库,用fopen函数来实现文件的翻开。fopen函数的调用方式通常为:FILE *fp;fp=fopen(文件名,使用文件方式);例如:fp=fopen(a1,r);它表示要翻开名字为a1的文件,使用文

7、件方式为“读入r代表read,即读入,fopen函数带回指向a1文件的指针并赋给fp,这样fp就和文件a1相联系了,或者说,fp指向a1文件。可以看出,在翻开一个文件时,将通知编译系统以下3个信息:需要翻开的文件名,也就是准备访问的文件的名字;使用文件的方式“读还是“写等;让哪一个指针变量指向被翻开的文件。使用文件的方式文件使用方式含 义r(只读)为输入打开一个文本文件w(只写)为输出打开一个文本文件a(追加)向文本文件末尾追加数据rb(只读)为输入打开一个二进制文件wb(只写)为输出打开一个二进制文件ab(追加)向二进制文件末尾追加数据r+(读写)为读/写打开一个文本文件w+(读写)为读/写

8、建立一个新的文本文件a+(读写)为读/写打开一个文本文件rb+(读写)为读/写打开一个二进制文件wb+(读写)为读/写建立一个新的二进制文件ab+(读写)为读/写打开一个二进制文件11.3.1 文件的翻开fopen函数说明:用r方式翻开的文件只能用于向计算机输入而不能用作向该文件输出数据,而且该文件应该已经存在,不能用r方式翻开一个并不存在的文件即输入文件,否那么出错。用w方式翻开的文件只能用于向该文件写数据即输出文件,而不能用来向计算机输入。如果原来不存在该文件,那么在翻开时新建立一个以指定的名字命名的文件。如果原来已存在一个以该文件名命名的文件,那么在翻开时将该文件删去,然后重新建立一个新

9、文件。11.3.1 文件的翻开fopen函数如果希望向文件末尾添加新的数据不希望删除原有数据,那么应该用a方式打 开。但此时该文件必须已存在,否那么将得到出错信息。翻开时,位置指针移到文件的末尾。用r+、w+、a+方式翻开的文件既可以用来输入数据,也可以用来输出数据。用r+方式时,该文件必须已经存在,以便能向计算机输入数据;用w+方式那么新建立一个文件,先向此文件写入数据,然后可以读此文件中的数据;用a+方式翻开的文件,原来的文件不被删除,位置指针移到文件末尾,可以添加,也可以读取。如果不能实现“翻开的任务,fopen函数将会带回一个出错信息。出错的原因可能是用r方式翻开一个并不存在的文件;磁

10、盘出故障;磁盘已满无法建立新文件等。此时fopen函数将带回一个空指针NULLNULL在文件中已被定义为0。常用下面的方法翻开一个文件:if(fp=fopen(file1,r)=NULL) printf(cannot open this filen); exit(0); 11.3.1 文件的翻开fopen函数即先检查翻开的操作是否出错,如果有错就在终端上输出“cannot open this file。exit函数的作用是关闭所有文件,终止正在调用的过程。待用户检查出错误,修改后再运行。用以上方式可以翻开文本文件或二进制文件,这是ANSI C的规定,用同一种缓冲文件系统来处理文本文件和二进制文

11、件。但目前使用的有些C编译系统可能不完全提供所有这些功能例如有的只能用r、w、a方式,有的C版本不用r+、w+、a+,而用rw、wr、ar等,注意所用系统的规定。11.3.1 文件的翻开fopen函数在向计算机输入文本文件时,将回车换行符转换为一个换行符,在输出时把换行符转换成为回车和换行两个字符。在用二进制文件时不进行这种转换,在内存中的数据形式与输出到外部文件中的数据形式完全一致,一一对应。11.3.1 文件的翻开fopen函数在程序开始运行时,系统自动翻开3个标准文件:标准输入、标准输出、标准出错输出。通常这3个文件都与终端相联系。因此以前我们所用到的从终端输入或输出都不需要翻开终端文件

12、。系统自动定义了3个文件指针stdin、stdout和stderr,分别指向终端输入、终端输出和标准出错输出也从终端输出。如果程序中指定要从stdin所指的文件输入数据,就是指从终端键盘输入数据。11.3.2 文件的关闭fclose函数在使用完一个文件后应该关闭它,以防止它再被误用。“关闭就是使文件指针变量不指向该文件,也就是文件指针变量与文件“脱钩,此后不能再通过该指针对原来与其相联系的文件进行读写操作。除非再次翻开,使该指针变量重新指向该文件。用fclose函数关闭文件,其调用的一般形式为:fclose(文件指针);11.3.2 文件的关闭fclose函数前面把翻开文件用fopen函数时所

13、带回的指针变量赋给了fp,现在通过fp把该文件关闭,即fp不再指向该文件。应该养成在程序终止之前关闭所有文件的习惯,如果不关闭文件将会丧失数据。因为,如前面讲述的,在向文件写数据时,是先将数据输到缓冲区,待缓冲区充满后才正式输出给文件。如果当数据未充满缓冲区而程序结束运行,就会将缓冲区中的数据丧失。用fclose函数关闭文件,可以防止这个问题,它先把缓冲区中的数据输出到磁盘文件,然后才释放文件指针变量。11.4 文件的读写 fputc函数和fgetc函数putc函数和getc函数fread函数和fwrite函数fprintf函数和fscanf函数其他读写函数11.4.1 fputc函数和fge

14、tc函数putc函数和getc函数 fputc函数fgetc函数fputc和fgetc函数使用举例11.4.2 fread函数和fwrite函数getc和putc函数可以用来读写文件中的一个字符,但是常常要求一次读入一组数据例如,一个实数或一个结构体变量的值,ANSI C标准提出设置两个函数fread和fwrite,用来读写一个数据块。它们的一般调用形式如下:fread(buffer,size,count,fp);fwrite(buffer,size,count,fp);其中:buffer:是一个指针。对fread来说,它是读入数据的存放地址;对fwrite来说是要输出数据的地址以上指的是起始

15、地址。size:要读写的字节数。count:要进行读写多少个size字节的数据项。fp:文件型指针。如果文件以二进制形式翻开,用fread和fwrite函数就可以读写任何类型的信息,如:fread(f,4,2,fp);11.4.2 fread函数和fwrite函数其中f是一个实型数组名。一个实型变量占4个字节。这个函数从fp所指向的文件读入2次每次4个字节数据,存储到数组f中。如果有一个如下的结构体类型:struct studentchar name10; int num; int age; char addr30;stud40;11.4.2 fread函数和fwrite函数结构体数组stud

16、有40个元素,每一个元素用来存放一个学生的数据包括姓名、学号、年龄、地址。假设学生的数据已存放在磁盘文件中,可以用下面的for语句和fread函数读入40个学生的数据:for(i=0;i40;i+) fread(&studi,sizeof(struct student),1,fp);同样,以下for语句和fwrite函数可以将内存中的学生数据输出到磁盘文件中去:for(i=0;i40;i+) fwrite(&studi,sizeof(struct student),1,fp);如果fread或fwrite调用成功,那么函数返回值为count的值,即输入或输出数据项的完整个数。11.4.3 fp

17、rintf函数和fscanf函数fprintf函数、fscanf函数与printf函数、scanf函数作用相似,都是格式化读写函数。只有一点不同:fprintf和fscanf函数的读写对象不是终端,而是磁盘文件。它们的一般调用方式为:fprintf(文件指针,格式字符串,输出表列);fscanf(文件指针,格式字符串,输入表列);例如:fprintf(fp,%d,%6.2f,i,t);它的作用是将整型变量i和实型变量t的值按%d和的格式输出到fp指向的文件上。如果i=3,那么输出到磁盘文件上的是以下字符串:11.4.3 fprintf函数和fscanf函数同样,用以下fscanf函数可以从磁盘

18、文件上读入ASCII字符:fscanf(fp,%d,%f,&i,&t);磁盘文件上如果有以下字符:那么将磁盘文件中的数据3送给变量i,送给变量t。用fprintf和fscanf函数对磁盘文件读写,使用方便,容易理解,但由于在输入时要将ASCII码转换为二进制形式,在输出时又要将二进制形式转换成字符,花费时间比较多。因此,在内存与磁盘频繁交换数据的情况下,最好不用fprintf和fscanf函数,而用fread和fwrite函数。11.4.4 其他读写函数putw和getw函数大多数C编译系统都提供另外两个函数:putw和getw,用来对磁盘文件读写一个字整数。例如:putw(10,fp);它的

19、作用是将整数10输出到fp指向的文件,而:i=getw(fp);的作用是从磁盘文件读一个整数到内存,赋给整型变量i。如果所用的C编译的库函数中不包括putw和getw函数,可以自己定义这两个函数。putw函数如下:putw(int i,FILE *fp)char *s; s=&i; putc(s0,fp); putc(s1,fp); return(i);putw和getw函数当调用putw函数时,如果用“putw(10,fp);语句,形参i得到实参传来的值10,在putw函数中将i的地址赋给指针变量s,而s是指向字符变量的指针变量,因此s指向i的第1个字节,s+1指向i的第2个字节。由于*(s

20、+0)就是s0,*(s+1)就是s1,因此,s0、s1分别对应i的第1字节和第2字节。顺序输出s0、s1就相当于输出了i的两个字节中的内容,如图11-3所示。getw函数如下:getw(FILE *fp)char *s; int i; s=&i; s0=getc(fp); s1=getc(fp); return(i);putw和getw并不是ANSI C标准定义的函数。但许多C编译系统都提供了这两个函数,有的C编译系统可能不以putw和getw命名这两个函数,而用其他函数名,使用时须注意。读写其他类型数据 如果用ANSI C提供的fread和fwrite函数,读写任何类型数据都是十分方便的。如

21、果所用的系统不提供这两个函数,用户只好自己定义所需函数。例如,可以定义一个向磁盘文件写一个实数用二进制方式的函数putfloat。putfloat(float num,FILE *fp)char *s; int count; s=# for(count=0;count4;count+) putc(scount,fp);同样可以编写出读写任何类型数据的函数。fgets函数和fputs函数fgets的作用是从指定文件读入一个字符串,如:fgets(str,n,fp);n为要求得到的字符长度,但只从fp指向的文件输入n1个字符,然后在最后加一个0字符,因此得到的字符串共有n个字符。把它们放到

22、字符数组str中。如果在读完n1个字符之前遇到换行符或EOF,读入即结束。fgets函数返回值为str的首地址。fputs函数的作用是向指定的文件输出一个字符串,如:fputs(China,fp);把字符串“China输出到fp指向的文件。fputs函数中第一个参数可以是字符串常量、字符数组名或字符型指针,字符串末尾0不输出。假设输出成功,函数值为0;失败时,为EOF。11.5 文件的定位rewind函数fseek函数和随机读写ftell函数11.5.1 rewind函数【例】有一个磁盘文件,第一次将它的内容显示在屏幕上,第二次把它复制到另一个文件中。#includemain()FILE *f

23、p1,*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);11.5.1 rewind函数在第一个循环结束后,将文件的内容显示在屏幕上,文件的位置指针已指到文件末尾,feof的值为非零真。执行rewind函数后,使文件的位置指针重新定位到文件的开头,并使feof函数的值恢复为0假。第二次循环将文件内容复制到另一个文件中,循环结束

24、后,文件的位置指针又指向文件末尾。11.5.2 fseek函数和随机读写对流式文件可以进行顺序读写,也可以进行随机读写。关键在于控制文件的位置指针,如果位置指针是按字节位置顺序移动的,就是顺序读写;如果能将位置指针按需要移动到任意位置,就是随机读写。所谓随机读写是指读写完上一个字符字节后,并不一定要读写其后续的字符字节,而可以读写文件中任意所需的字符字节。用fseek函数可以实现改变文件的位置指针。其调用形式如下:fseek(文件类型指针,位移量,起始点)“起始点用0、1或2代替,0代表“文件开始,1代表“当前位置,2代表“文件末尾。ANSI C标准指定的名字如表所示。 ANSI C标准指定的

25、名字起 始 点名 字用数字代表文件开始SEEK_SET0文件当前位置SEEK_CUR1文件末尾SEEK_END211.5.2 fseek函数和随机读写位移量指以“起始点为基点向前移动的字节数。ANSI C和大多数C版本都要求位移量是long型数据。这样当文件的长度大于64K时不至于出问题。ANSI C标准规定在数字的末尾加一个字母L就表示是long型。fseek函数一般用于二进制文件,因为文本文件要发生字符转换,计算位置时往往会发生混乱。下面是fseek函数调用的几个例子:fseek(fp,100L,0); /*将位置指针移到离文件头100个字节处*/fseek(fp,50L,1); /*将位置指针移到离当前位置50个字节处*/fseek(fp,-10L,2); /*将位置指针从文件末尾处向后退10个字节*/利用fseek函数就可以实现随机读写了。11.5.3 ftell函数ftell函数的作用是得到流式文件中的当前位置,用相对于文件开头的位移量来表示。由于文件中的位置指针经常移动,人们往往不容易知道其当前位置。用ftell函数可以得到当前位置。如果ftell函数返回值为-1L,表示出错。例如:i=ftell(fp);if(i=-1L) printf(errorn);变量i存放当前位置,如调用函数出错如不存在此文件,那么输出“error。11.6 出错的检

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论