书签 分享 收藏 举报 版权申诉 / 124
上传文档赚钱

类型《C语言与程序设计教程》课件第8章.ppt

  • 上传人(卖家):momomo
  • 文档编号:8095501
  • 上传时间:2024-11-26
  • 格式:PPT
  • 页数:124
  • 大小:573KB
  • 【下载声明】
    1. 本站全部试题类文档,若标题没写含答案,则无答案;标题注明含答案的文档,主观题也可能无答案。请谨慎下单,一旦售出,不予退换。
    2. 本站全部PPT文档均不含视频和音频,PPT中出现的音频或视频标识(或文字)仅表示流程,实际无音频或视频文件。请谨慎下单,一旦售出,不予退换。
    3. 本页资料《《C语言与程序设计教程》课件第8章.ppt》由用户(momomo)主动上传,其收益全归该用户。163文库仅提供信息存储空间,仅对该用户上传内容的表现方式做保护处理,对上传内容本身不做任何修改或编辑。 若此文所含内容侵犯了您的版权或隐私,请立即通知163文库(点击联系客服),我们立即给予删除!
    4. 请根据预览情况,自愿下载本文。本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
    5. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007及以上版本和PDF阅读器,压缩文件请下载最新的WinRAR软件解压。
    配套讲稿:

    如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。

    特殊限制:

    部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。

    关 键  词:
    C语言与程序设计教程 语言 程序设计 教程 课件
    资源描述:

    1、第第8章章 文件文件 8.1 文件的概念8.2 文件的打开与关闭8.3 文件的读写8.4 文件的定位与随机读/写8.5 典型例题精讲 8.1 文件的概念文件的概念所谓文件,是指一组相关数据的有序集合。这个数据集合有一个名称,即文件名。实际上以前我们已多次使用过文件,例如源文件、目标文件、可执行文件、库文件(头文件)等。本章主要介绍C语言的数据文件。8.1.1 文件的分类文件的分类文件通常是驻留在外部介质(如磁盘、U盘等)上的,在使用时才调入到内存中来。从用户角度看,文件可以分为普通文件和设备文件两种。普通文件是指驻留在磁盘或其他外部介质上的一个有序数据集合,可以是我们通常使用的源程序文件、目标

    2、文件、可执行文件,也可以是一组等待输入处理的原始数据,或者是一组等待输出的结果数据;对于源文件、目标文件、可执行文件可以称做程序文件,而用于输入或输出的数据则称做数据文件。设备文件是指与主机相联的各种外部设备:如显示器、打印机、键盘等,即把实际的物理设备抽象为逻辑设备,通常把显示器定义为标准输出文件,如经常使用的printf、putchar函数就属于这类输出;而键盘通常被指定为标准输入文件,如scanf、getchar函数就属于这类输入。使用文件的优点如下:(1)程序与数据分离:数据的改动不引起程序的改动。(2)数据共享:不同的程序可以访问同一个数据文件中的数据。(3)延长数据的生存周期:能够

    3、用文件长期保存程序运行的中间数据或结果数据。在C语言中,文件被看做是字符(或字节)的序列,即文件是由一个个字符(或字节)按一定的顺序组成的,这个字符(或字节)序列称之为字节流。文件以字节为单位进行处理而且并不区分类型,这样能够增强数据处理的灵活性。输入/输出字节流的开始和结束只受程序的控制而不受字节流中的某个字符(如换行符n)的控制。通常也把这种文件称为流式文件。根据数据存储方式的不同,C语言中的文件可分为文本文件和二进制文件两种类型。以ASCII码字符形式存储的文件称为文本文件(又称ASCII文件)。在文本文件中,每一个字节存放一个ASCII码字符。由于ASCII码这种字节与字符对应的方式,

    4、因而便于对字符进行逐个处理,也便于输出字符,但文本文件与二进制文件相比则需要占用更大的存储空间。在二进制文件中,数据是以二进制形式存储的,这种存储方式结构紧凑并能节省大量的存储空间。在二进制文件中,一个字节并不直接对应一个字符,它需要转换后才能以字符的方式输出。不过,计算机处理的数据都是二进制的。所以当从二进制文件中读取数据时,无需转换就可以直接将数据读入内存进行数据的运算和处理,从而提高了文件的处理速度。例如在两种文件存储方式下,十进制数5678在内存中的存储示意见图8-1。图8-1 十进制数5678在内存中的两种存储方式示意由图8-1可知,十进制数5678以ASCII码方式存储需要占用4个

    5、字节,而采用二进制方式存储则只需要占用2个字节。注意,二进制文件虽然也可以在屏幕上显示,但由于不是以字符方式存储的,所以显示的内容将无法阅读。因为C语言在处理这些文件时并不区分类型,即都是看成字节流按字节进行处理的,所以才造成了二进制文件显示内容无法看懂。从文件的读/写方式上来看,文件还可以分为顺序读/写文件和随机读/写文件两种。顺序读/写文件是指按文件从头到尾的顺序读出或写入数据,随机读/写文件则可以读/写文件中任意位置上的数据。8.1.2 文件指针变量及文件操作过程在C语言中,对文件的访问是通过文件指针来实现的,即用一个指针变量来指向一个文件,这个指针变量就称为文件指针变量。通过文件指针变

    6、量就可以对由它所指的文件进行各种操作。定义文件指针变量的一般形式为:FILE*指针变量标识符;其中,FILE应大写,它实际上是由系统定义的一个结构体类型,该结构体中含有文件名、文件状态和文件当前位置等信息。在编写程序时无需关心FILE结构体类型的细节,只是当需要使用一个数据文件时,定义一个指向FILE结构体类型的指针变量即可。例如:FILE*fp;表示fp是一个指向FILE结构体类型的指针变量,通过fp就可以找到与它相关联的文件,并对该文件实施所需的操作。通过程序可以对文件进行操作,即从文件中读取数据或向文件中写入数据。文件操作的步骤通常如下:(1)建立或打开文件。(2)从文件中读取数据或向文

    7、件中写入数据。(3)关闭文件。上述三个步骤是按顺序进行的,所以打开文件是对文件进行读/写的前提;打开文件就是将指定的文件与当前执行的程序联系起来,建立了外存数据文件与内存中这个程序的数据传递通道,也即为文件的读/写操作做好准备。当需要为写操作打开一个文件时,如果该文件不存在,则系统会先创建这个文件;当需要为读操作打开一个文件时,则这个文件必须是已经存在的文件,否则就会出错。数据文件可以通过文本编辑程序建立(如同建立源程序文件一样);也可在程序中打开创建一个数据文件,然后通过写操作向该数据文件写入数据。从文件中读取数据,就是从指定的外存文件中读取数据,然后存入内存中程序的数组或变量。文件存储在外

    8、存上,而程序则在内存中运行,运行所产生的结果(数据)总是先暂存在内存中的文件缓冲区,当缓冲区装满数据后,数据才整块的被送到外存文件中。如果在内存中运行的程序需要获取(读出)外存文件中的数据,也是将外存文件中的一批数据一次性读到内存中的文件缓冲区,然后再由程序从该缓冲区中取出数据,送入程序中相应的数组或变量。图8-2给出了外存文件与内存中程序之间传递数据的示意。图8-2 外存文件与内存程序的数据传递示意因此,建立或打开文件就是在内存中开辟一个文件缓冲区,即将外存文件、内存程序与文件缓冲区这三者联系起来,形成一个内存程序与外存文件之间的数据传输通道。而关闭文件则是将文件缓冲区未放满的输出数据(如果

    9、有的话)写到外存文件上,否则可能造成输出数据的丢失;然后撤消内存中的文件缓冲区,即关闭了外存文件与内存程序之间的数据传输通道。所以,只要程序需要访问外存文件,就必须先执行建立或打开文件的操作,在文件读/写操作结束后,还必须执行关闭文件的操作。8.2 文件的打开与关闭文件的打开与关闭 C语言并不是直接通过文件名对文件进行操作,而是首先创建一个和文件联系的指针变量,然后通过文件指针变量对文件进行操作。因此,文件在进行读/写操作之前首先要打开,使用完后要关闭;即进行文件操作必须遵守“打开读/写关闭”的操作流程。所谓打开文件,实际上是建立文件的各种相关信息,并使文件指针变量指向该文件,以便进行读/写操

    10、作。关闭文件则是断开文件指针变量与文件之间的联系,即禁止再对该文件进行操作。在C语言中,文件操作都是由库函数来完成的。8.2.1 文件的打开文件的打开使用文件之前要打开文件。打开文件完成以下工作:(1)在外存设备中寻找或创建一个指定文件;(2)在内存中建立文件缓冲区;(3)建立与文件联系的指针变量;(4)确定文件的使用方式。C语言通过函数fopen来打开一个文件,其调用的一般形式为:文件指针变量=fopen(文件名,打开文件方式);其中,文件指针变量必须是被说明为FILE类型的指针变量;文件名是被打开的文件名,它可以是字符串常量或字符串数组;打开文件方式是指文件的类型和操作要求。例如:FILE

    11、*fp;fp=(file1,r);其功能是在当前目录下打开文件file1,只允许对文件进行读操作,并使指针变量fp指向该文件。又如:FILE*fp1;fp1=(c:h.txt,rt);其功能是打开c盘根目录下的文件h.txt,这是一个文本文件,只允许按字符方式进行读操作(rt即为read text),两个反斜杠中的第一个表示转义字符,即表示第二个是一个字符;在此表示根目录。使用文件的方式共有12种,表8.1给出它们的符号和意义。表表8.1 文件打开方式文件打开方式表中“rb”即英文“read binary”的缩写,而“wt”则是英文“write text”的缩写;此外,表8.1中的t一律可以略

    12、去,即“rt”可直接写成“r”,“wt+”可直接写成“w+”。文件打开方式的几点说明:(1)文件打开方式由r、w、a、t、b、+这6个字符拼成,各字符的含义如下:r(read):读w(write):写a(append):追加t(text):文本文件,可省略不写b(binary):二进制文件+:读和写(2)用“r”打开一个文件时,该文件必须已经存在,且只能从该文件读出数据。(3)用“w”打开的文件只能向该文件写入数据。若打开的文件不存在,则以指定的文件名创建一个新文件;若打开的文件已经存在,则删除该文件(即意味着该文件中的原有数据全部丢失),然后以这个文件名重新创建一个新文件。(4)若要向一个已

    13、经存在的文件尾部追加新的数据,则只能用“a”方式打开文件,但这个文件必须是已经存在的,否则出错。(5)如果打开一个文件时出现错误,则函数fopen将返回一个空指针值NULL。因此,常用下面的程序段打开文件:if(fp=fopen(c:hh,rb)=NULL)/*打开文件是否失败*/printf(error on open c:hh file!n);/*显示打开文件失败信息*/getchar();exit(1);/*退出程序*/这段程序的意义是,如果返回的指针值为空,就表示不能打开c盘根目录下的hh文件,即给出提示信息“error on open c:hh file!”,下一行getchar的功

    14、能则是从键盘读入一个字符,但不在屏幕上显示,它的作用仅是等待,只有从键盘上敲入任意键后,程序才继续执行,因此可以利用这个等待时间阅读出错提示,即敲键后执行语句“exit(1);”退出程序。当然,也可以不要“getchar();”语句。另外要注意的是,程序中如果使用语句“exit(1);”,则C程序开始处必须包含“stdlib.h”头文件。(6)把一个文本文件读入内存时,要将ASCII码转换成二进制码;而把文件以文本方式写入外存文件时,也要将二进制码转换成ASCII码。因此文本文件的读写要花费较多的转换时间。(7)标准输入文件(键盘)、标准输出文件(显示器)、标准出错输出文件(出错信息)是由系统

    15、自动打开的,可以直接使用。系统中定义了三个文件指针变量stdin、stdout和stderr来分别指向标准输入文件,标准输出文件和标准出错输出文件。8.2.2 文件的关闭文件的关闭文件一旦使用完毕应当立即关闭,以避免文件数据的丢失或者文件被再次误用,关闭文件完成以下工作:(1)如果文件是以“写”或“读写”方式打开的,则把缓冲区中还未存入文件的剩余数据存储到文件中。(2)断开文件指针变量与这个文件的联系,此时文件指针变量可用于指向其他文件。(3)释放内存中的文件缓冲区。C语言通过函数fclose来关闭一个文件,其调用的一般形式为:fclose(文件指针变量);例如:fclose(fp);其作用是

    16、关闭fp所指向的文件。正常完成关闭文件操作时,函数fclose返回值为0。如果返回非零值,则表示关闭出错。在程序中,一个文件使用完毕后应及时关闭。特别要注意的是:在程序结束之前应关闭所有已打开的文件以防止数据的丢失。因为向文件写数据时,是先将数据写到该文件在内存的缓冲区,当缓冲区满时才一次性将缓冲区中的数据传送给外存文件。如果程序运行结束时,这个内存缓冲区仍存有数据,但是由于缓冲区未满而并没有将这些数据传给外存文件,则必须使用函数fclose来关闭文件,由系统强制将内存缓冲区中的剩余数据传送给外存文件,然后释放内存缓冲区及文件指针变量,即中止程序与这个外存文件的联系;否则,程序中传送给外存文件

    17、的某些数据可能并没有真正传给外存文件,而只是暂存于内存缓冲区中,在没有用fclose关闭文件的情况下,结束程序的运行将会造成这些数据的丢失。注意,由系统打开的标准输入、输出文件,在程序运行结束时会自动关闭。例8.1 以写方式打开一个在C盘下名为test.txt的文本文件。解 程序如下:#include#includevoid main()FILE*fp;if(fp=fopen(c:test.txt,w)=NULL)printf(Can not open file!n);exit(1);fclose(fp);8.3 文件的读写文件的读写 文件打开之后,就可以对文件进行读写操作了,在C语言中提供了

    18、多种文件读/写函数。包括字符、字符串,数据块和格式化读/写等。需要注意的是:读/写文本文件和读/写二进制文件所使用的函数是不同的。文件读写函数如下:字符读/写函数:fgetc 和 fputc字符串读/写函数:fgets 和 fputs数据块读/写函数:fread 和 fwrite格式化读/写函数:fscanf 和 fprintf8.3.1 字符读字符读/写函数写函数字符读/写函数是以字节为单位的读写函数,每次可以从文件读取或向文件写入一个字符。1.写字符函数fputc写字符函数fputc调用的一般形式为:fputc(字符量,文件指针变量);函数fputc的功能是把一个字符写入指定文件的当前读写

    19、指针位置,然后将该文件的读写指针顺序后移一个字符位置,其中待写入的字符量可以是字符常量或字符变量。注意,文件的读写指针不是文件指针变量,文件指针变量是用户定义的指针变量,是用来指向文件的,即建立程序与文件的联系;而文件读写指针是系统设置的内部指针,是用于文件读/写数据的,即定位于文件中需要进行读/写操作的那个数据位置。例如:fputc(a,fp);其功能是将字符a写入fp所指文件的当前读写指针位置。使用函数fputc时需要注意以下几点:(1)给文件写数据可以用写“w”、读写“w+”、追加写“a”和读与追加写“a+”方式打开文件。如果用读/写方式打开一个已经存在的文件,则文件原有的数据将被删除;

    20、写入字符的操作是从文件开始处依次写入。若使用追加写方式打开文件,则文件原有的数据将被保留,写入字符的操作则从文件尾部开始写入。如果被写入的文件不存在,则这几种写方式都将创建一个新文件,然后再开始写操作。(2)函数fputc有一个返回值,如果写入成功,则返回所写入的字符,否则返回文件结束标志EOF(值为-1)表示写操作失败。(3)每写入一个字符,文件内部的读写指针将顺序后移一个字符位置,该指针由系统自动设置,用于指示文件的当前读写位置。2.读字符函数fgetc读字符函数fgetc调用的一般形式为:字符变量=fgetc(文件指针变量);函数fgetc的功能是由文件指针变量所指的文件中,读出一个字符

    21、并送入赋值号“=”左边的字符变量,然后将文件内部的读写指针移至文件的下一个字符位置。例如:ch=fgetc(fp);其功能是从打开的文件(由fp所指)中读取一个字符并送入字符变量ch中,同时文件内部的读写指针后移一个字符位置。使用函数fgetc时需要注意以下几点:(1)在函数fgetc调用中,读取文件中字符数据的这个文件必须是以读或读/写方式打开的。(2)文件内部有一个读写指针用来指示文件的当前读写位置。在文件打开时,该读写指针总是指向文件中的第一个字符(字节),使用函数fgetc后,该读写指针将后移一个字节位置,因此可以连续多次使用函数fgetc来读取文件中的多个字符。注意,VC+6.0中f

    22、putc也可用putc表示,fgetc也可用getc表示。例8.2 在c盘上建立一个myfile.txt文件,并将字符串“How are you”写入文件,然后从该文件中读出数据并显示在屏幕上。解 程序如下:#includevoid main()FILE*fp;char ch,a20=How are you,*p=a;fp=fopen(c:myfile.txt,w);/*创建myfile.txt文件用于写操作*/while(*p!=0)fputc(*p,fp);/*将*p(p所指数组元素的内容)写入文件*/p+;fclose(fp);/*关闭文件*/fp=fopen(c:myfile.txt,

    23、r);/*打开myfile.txt文件用于读操作*/ch=fgetc(fp);/*从文件中读取一个字符*/while(ch!=EOF)/*EOF为文件结束标志*/putchar(ch);/*将读取的字符显示在屏幕上*/ch=fgetc(fp);/*继续从文件中读取字符*/fclose(fp);/*关闭文件*/程序执行的写、读过程示意见图8-3。程序首先通过语句“fp=fopen(c:myfile.txt,w);”在c盘根目录下创建了一个名为myfile.txt的文件,此时文件的读写指针是指向该文件的第一个字符位置(见图8-3(a)。接下来通过语句“fputc(*p,fp);”将头一个字符H(*

    24、p此时为a0)写到文件中;然后,文件读写指针后移一个字符位置,“p+;”也使指针变量p指向a1。这一写操作持续到将数组a中的整个字符串全部写入到文件中为止,并且读写指针的定位如图8-3(b)所示。因此,无法由指向文件结束标志(EOF)位置的读写指针来读取文件中的数据;所以必须先关闭文件,然后再用读方式打开该文件,这时读写指针就又重新定位于该文件的第一个字符位置,也即可以从这个位置开始读取文件的数据了(见图8-3(c)所示)。图8-3 程序执行的读写示意8.3.2 字符串读字符串读/写函数写函数1.写字符串函数fputs写字符串函数fputs调用的一般形式为:fputs(字符串,文件指针变量);

    25、函数fputs的功能是向指定的文件写入一个字符串。其中,字符串可以是字符串常量,也可以是字符数组名或指向字符串的指针变量。例如:fputs(abcd,fp);其功能是把字符串“abcd”写入fp所指的文件中,写操作成功,则函数将返回0值,写操作失败,则返回非0值。2.读字符串函数fgets读字符串函数fgets调用的一般形式为:fgets(字符数组名,n,文件指针变量);函数fgets的功能是从指定文件中读出一个字符串到程序的字符数组中。其中,n是一个正整数,表示从文件中读出的字符串不超过n-1个字符,并且在读入的最后一个字符后添加上字符串结束标志0。注意,函数fgets从文件中读取字符直到遇

    26、到回车符n或文件结束标志EOF为止,或者直到读入了所给定的字符个数(n-1个字符)为止。例如:fgets(str,n,fp);其功能是从fp所指文件中读取n-1个字符送入字符数组str中,并在其后加上字符串结束标志0(即传给字符数组str的是一个字符串)。函数读成功,则返回str指针值(数组str的首地址),失败则返回一个空指针NULL。例8.3 用字符串读/写函数实现例8.2功能。解 程序如下:#includevoid main()FILE*fp;char a20=How are you,b20;fp=fopen(c:myfile.txt,w);fputs(a,fp);fclose(fp);

    27、fp=fopen(c:myfile.txt,r);fgets(b,12,fp);fclose(fp);puts(b);对于字符串的读写,采用字符串读/写函数实现起来要比字符读/写函数方便。在程序中,当将一个字符串写到文件后,仍然要先关闭文件,然后再用读方式打开文件。这样文件内部的读写指针就重新定位于文件的第一个字符上,此时才可以使用函数fgets来读取文件中的数据,如果在执行了“fputs(a,fp);”语句之后就接着执行“fgets(b,12,fp);”语句,则由于该写指针定位于文件尾而无法读取文件中的数据。例8.4 有以下程序:#includevoid WriteStr(char*fn,c

    28、har*str);void main()WriteStr(t1.dat,start);WriteStr(t1.dat,end);void WriteStr(char*fn,char*str)FILE*fp;fp=fopen(fn,w);fputs(str,fp);fclose(fp);程序运行后,文件t1.dat中的内容是 。A)start B)end C)startend D)endrt 解 函数WriteStr有两个字符指针形参,即fn用来接受文件名实参,而str用来接受字符串的地址。由于函数WriteStr中文件打开的方式为“w”,即用写方式打开一个文本文件,而这种打开方式是:如果指定的

    29、文件t1.dat不存在,则新建名为t1.txt的文件;否则删除该文件,然后以该文件名重新创建一个新文件。因此,在主函数两次调用函数WriteStr时,写入的是同一个文件t1.dat;故只有最后一次写入的字符串有效,即选B。8.3.3 数据块读数据块读/写函数写函数1.写数据块函数fwriteC语言在文件操作中提供了用于整块数据的写函数fwrite,该函数可用来写一组数据;如一个数组、一个结构体变量的值。写数据块函数fwrite调用的一般形式为:fwrite(buffer,size,count,fp);其中,buffer是一个指针,表示存放输出数据的首地址;size表示数据块的字节数(等于该数据

    30、块中数据的个数数据类型占用的字节数);count表示要写到文件的数据块的块数;fp则为文件指针变量。也即,fwrite每次是将count个数据块且每块大小为size字节的数据(如一个结构体变量数组)写入到文件中,然后读写指针移至写入的count个数据块后等待下一次数据块的写入。如果所写入的数据块块数小于count值,就出现写错误。例如,设有定义:int a10=1,2,3,4,5,6,7,8,9,10;则使用函数fwrite将数组整体写入到文件的语句为:fwrite(a,40,1,fp);其功能是:从数组a的首地址开始,一次将40个字节(一个整型数占4个字节,即10个整型数据)写入到fp所指的

    31、文件中。如果不知道一个数据块的大小,也可以采用下面的形式来写数据:fwrite(a,10*sizeof(int),1,fp);2.读数据块函数freadC语言在文件操作中也提供了用于整块数据的读函数fread来读取一组数据,如一个数组、一个结构体变量的值。读数据块函数fread调用的一般形式为:fread(buffer,size,count,fp);其中,buffer是一个指针,表示存放从文件读出数据的首地址;size和fp与fwrite中的size和fp相同,而count则表示要从文件中读出的数据块的块数。例如:fread(a,4,5,fp);假定a是一实型数组名,则上述语句的功能是:从fp

    32、所指的文件中每次读出4个字节(一个实数的大小)送入程序中的a数组中,连续读5次;即一共读了5个实数到数组a中。文件中的读写指针将随所读数据块的字节数后移相应个字节位置,即定位于下一个未读的数据块位置。如果读取的数据块的块数少于fread函数调用时所要求的数目(即count值),则可能出现错误,或者已经到达了文件末尾。例8.5 求下面程序执行后的输出结果。#includevoid main()FILE*fp;int a10=1,2,3,0,0,i;fp=fopen(d1.dat,wb);fwrite(a,sizeof(int),5,fp);fwrite(a,sizeof(int),5,fp);f

    33、close(fp);fp=fopen(d1.dat,rb);fread(a,sizeof(int),10,fp);fclose(fp);for(i=0;i10;i+)printf(%d,ai);printf(n);解 程序首先定义了一个文件指针变量fp,然后通过函数fopen打开一个名为d1.dat的文件,参数“wb”表示以写方式打开一个二进制文件,然后通过函数fwrite将数组a的前5个元素值顺序写入了d1.dat文件中。注意,为什么两次写入文件都是数组a的前5个元素呢?因为两次写操作fwrite中的输出数据首地址都是a,即都是从数组a的第一个元素开始将连续的5个元素值写入文件d1.dat中

    34、的;其二,是否第二次写入的5个数据会覆盖掉第一次写入的5个数据呢?由于在第一次写和第二次写之间并没有其他操作,故第一次执行fwrite写操作后,读写指针是定位于已写入文件的5个数据之后的位置,当第二次执行fwrite写操作时,即从这个位置开始再写入数组a的前5个数据,因此并不会覆盖掉第一次写入的5个数据。接下来使用函数fclose关闭d1.dat文件,然后又用函数fopen再次打开d1.dat文件。此时,读写指针又定位于d1.dat的第一个数据位置,这时执行函数fread则将d1.dat中存放的10个数据顺序读入a数组中。因此,最终通过for语句输出a数组中的10个元素值为1,2,3,0,0,

    35、1,2,3,0,0,。8.3.4 格式化读格式化读/写函数写函数文件中的格式化读/写与数据的标准输入/输出基本相似。文件中的格式化读/写函数fscanf和fprintf 与标准输入/输出函数scanf和printf的区别就在于它们的读写对象不同:一个是外存文件而另一个是键盘和显示器。1.格式化写函数fprintf格式化写函数fprintf调用的一般形式为:fprintf(文件指针变量,格式控制字符串,输出项列表);其中,书写格式与函数printf相比除了多了一个文件指针变量外,其余完全与函数printf的格式相同。例如:fprintf(fp,%d%d,i,j);其返回值为实际写入文件的字节数,

    36、如果写出错,则返回EOF(即-1)。2.格式化读函数格式化读函数fscanf格式化读函数fscanf调用的一般形式为:fscanf(文件指针变量,格式控制字符串,输入项地址列表);其中,书写格式与函数scanf相比除了多了一个文件指针变量外,其余完全与函数scanf的格式相同。例如:fscanf(fp,%d%c,&i,&ch);其返回值为实际读出的字节数,如果调用失败,则返回EOF(即-1)。例8.6 求下面程序执行后的输出结果。#includevoid main()FILE*fp;int i=20,j=30,k,n;fp=fopen(d1.dat,w);fprintf(fp,%dn,i);f

    37、printf(fp,%dn,j);fclose(fp);fp=fopen(d1.dat,r);fscanf(fp,%d%d,&k,&n);printf(%d,%dn,k,n);fclose(fp);解 本题中,首先用函数fopen以写方式打开d1.dat文件,然后两次通过函数fprintf写入i值(后加n)和j值(后加n),其文件存储示意如图8-4所示。接着用函数fclose关闭该文件。当用函数fopen再次以读方式打开d1.dat文件时,此时读写指针即定位于文件的第1个字符2处。这时用fscanf将文件中的数据读给程序中整型变量k和n,由于数据在文件中是以字符方式存放的,所以就如同scanf

    38、语句输入数据一样,一个数据的结束标志要么是空格符,要么是回车符,因此是将20读给了变量k,30读给了变量n;也即最终语句“printf(%d,%dn,k,n);”的输出结果为20,30。图8-4 执行两次fprintf后文件d1.dat的存储示意例8.7 有以下程序:#includevoid main()FILE*fp;int k,n,a6=1,2,3,4,5,6;fp=fopen(d2.dat,w);fprintf(fp,%d%d%dn,a0,a1,a2);fprintf(fp,%d%d%dn,a3,a4,a5);fclose(fp);fp=fopen(d2.dat,r);fscanf(fp

    39、,%d%d,&k,&n);printf(%d,%dn,k,n);fclose(fp);程序运行后的输出结果是 。A)1,2 B)1,4 C)123,4 D)123,456 解 程序执行两次fprintf后文件d2.dat的存储示意如图8-5所示。由例8.6可知,再次从文件d2.dat读出数据送给整型变量k,n的分别是123和456。因此应选择D。另外,分散的数据读入文件后,如果没有用空格符或回车换行符分隔开,则当再次从文件中读出时,这些数据就连到一起成了一个数据,这一点要引起足够的重视。图8-5 执行两次fprintf后文件d2.dat的存储示意8.4 文件的定位与随机读文件的定位与随机读/写

    40、写 前面介绍的对文件的读/写方式都是顺序读/写,即读只能从文件首开始,写只能从文件首或文件尾开始,文件内部的读写指针按所读/写的数据长度顺序后移进行读/写。但在实际应用中经常需要读/写文件中某个指定位置上的数据,即能够将文件内部的读写指针根据需要移动到文件中任意的数据位置上,然后再进行读/写,这种读/写方式称为随机读写。实现随机读/写的关键是使读写指针能够移动到指定的数据位置上,这称之为文件的定位。实现文件定位是通过移动文件内部的读写指针来实现的,完成这个功能的C语言函数主要有两个,即rewind函数和fseek函数。1.定位于文件首函数rewind函数rewind调用的一般形式为:rewin

    41、d(文件指针变量);其功能是把文件内部的读写指针重新移到文件的开始处,该函数没有返回值,仅仅是执行移动文件内部读写指针的操作。例8.8 用程序实现将源文件file1.txt复制到目标文件file2.txt;然后显示所复制的file2.txt内容。解 程序如下:#includevoid main()FILE*pin,*pout;pin=fopen(file1.txt,r);pout=fopen(file2.txt,w+);while(!feof(pin)/*当文件未结束时*/putc(getc(pin),pout);rewind(pout);while(!feof(pout)putchar(ge

    42、tc(pout);fclose(pin);fclose(pout);当程序执行完第一个while循环时,目标文件file2.dat就复制完成了,此时两个文件的读写指针都已移到文件的未尾;由于程序还要在屏幕上显示所复制的目标文件内容。因此在语句“rewind(pout);”的作用下,将目标文件的读写指针又重新调回到文件的开始位置。如果用前面介绍的方法,则需要先关闭file2.dat文件,接着再以读方式打开file2.dat文件,然后才能显示所复制的file2.dat内容。因此,使用函数rewind将使文件操作更加简捷。此外,在程序中还使用了文件结束位置判断函数feof,当文件结束时,feof返回

    43、1值,否则返回0值。例8.9 有以下程序:#includevoid main()FILE*pf;char*s1=China,*s2=Beijing;pf=fopen(abc.dat,wb+);fwrite(s2,7,1,pf);rewind(pf);fwrite(s1,5,1,pf);fclose(pf);以上程序执行后abc.dat文件的内容是 。A)China B)Chinang C)ChinaBeijing D)Beijing China解 程序通过函数fopen以“wb+”方式新建一个可读/写的二进制文件abc.dat(见图8-6(a)。然后使用函数fwrite写入字符串s2的前“71

    44、字节”个字符。注意,由于是一个字节一个字节的以二进制方式读入字符,因此存储内容没有发生变化。现在的文件abc.dat中的内容以字符方式看仍为“Beijing”(见图8-6(b)。接下来程序使用函数rewind将文件的读写指针调回到文件的起始位置(见图8-6(c),然后又调用函数fwrite写入字符串s1的前“51字节”个字符,所以文件原有内容“Beijing”中的前5个字符被“China”覆盖(见图8-6(d)。结果应选B。图8-6 程序执行中文件abc.dat变化示意注意,打开一个文件时,文件结束标志“EOF”就在第一个位置,然后每写入一个字节数据,“EOF”就后移一个字节,当第二次由文件开

    45、始处写入字符时,这个“EOF”已在第一次写入文件的数据“Beijing”后面。2.移动读写指针函数fseek函数fseek调用的一般形式为:fseek(文件指针变量,位移量,起始位置);其中,文件指针变量指向需要移动读/写位置的文件,位移量是指读写指针需要移动的字节数,大于0表明新的读/写位置在起始位置的后面,小于0表明新的读/写位置在起始位置的前面,当用常量表示位移量时,通常要求加后缀“L”;起始位置表示从何处开始计算位移量。规定的起始位置有三种:文件首、当前位置和文件尾,其表示方法见表8.2。表表8.2 起始位置的表示方法起始位置的表示方法注意,位移量也可由sizeof运算符给出。size

    46、of是C语言的一个单目运算符,它的引用格式为:sizeof 变量名或者:sizeof(类型名)例如:fseek(fp,-2L*sizeof(int),SEEK_CUR);则表示把文件的读写指针由当前位置开始向前移动两个整型数据位置。需要说明的是,函数fseek一般用于二进制文件;在文本文件中由于要进行字符到二进制的转换,这样fseek计算的位置就会出错(即与实际位置不符)。在文件随机读/写过程中,通过fseek确定读写指针位置之后,就可以采用前面介绍的任何一种读/写函数来进行读/写了。由于一般是读/写一个数据块,因此常用函数fread和fwrite来实现。例8.10 给出下面程序的运行结果。#

    47、includevoid main()FILE*fp;int i,a=1,2,3,4,5,6;fp=fopen(d1.dat,w+b);fwrite(a,sizeof(int),6,fp);fseek(fp,sizeof(int)*3,SEEK_SET);fread(a,sizeof(int),3,fp);fclose(fp);for(i=0;i6;i+)printf(%d,ai);printf(n);解 在程序中,首先通过fopen打开d1.dat文件,参数“w+b”即以二进制读/写方式打开d1.dat文件。注意,字符“w”、“+”、“b”可任意组合。如果文件“d1.dat”不存在,则新建一个

    48、“d1.dat”文件。打开文件后,通过函数fwrite将数组a中的前6个元素顺序写入文件d1.dat(见图8-7(a)。接着通过函数fseek使文件的读写指针移到文件开始位置算起的第3个整型数位置(见图8-7(b),然后使用函数fread顺序读出文件读写指针所指的3个数送到数组a的前3个元素中。所以读入a0a2中的数据是4、5、6,也即数组a中现在的内容是:4,5,6,4,5,6,。故最终输出的结果是:4,5,6,4,5,6,。图8-7 读写指针移动示意例8.11 有以下程序:#includevoid main()FILE*fp;int i,a4=1,2,3,4,b;fp=fopen(data

    49、.dat,wb);for(i=0;i4;i+)fwrite(&ai,sizeof(int),1,fp);fclose(fp);fp=fopen(data.dat,rb);fseek(fp,-2L*sizeof(int),SEEK_END);fread(&b,sizeof(int),1,fp);fclose(fp);printf(%dn,b);程序执行的输出结果是 。A)2 B)1 C)3 D)4解 在程序中,首先通过函数fopen打开data.dat文件,打开方式“wb”是以二进制写方式打开data.dat文件的。打开文件后,通过for循环中的fwrite语句将数组a中的4个元素值写入data

    50、.dat文件(见图8-8(a),然后关闭data.dat文件。接下来通过函数fopen以“rb”方式即二进制读方式打开data.dat文件。随后由函数fseek让读写指针从文件未尾向前移动两个整型数据(int)位置(见图8-8(b),最后通过函数fread从文件的读写指针处读取一个整型数到程序中的整型变量b中;由图8-8(b)可知,读取的数是3,因此最后输出的b值为3,也即本题应选C。图8-8 读写指针移动示意8.5 典型例题精讲典型例题精讲 例8.12 有以下程序:#includevoid main()FILE*fp;int i,k,n;fp=fopen(d1.dat,w+);for(i=1

    展开阅读全文
    提示  163文库所有资源均是用户自行上传分享,仅供网友学习交流,未经上传用户书面授权,请勿作他用。
    关于本文
    本文标题:《C语言与程序设计教程》课件第8章.ppt
    链接地址:https://www.163wenku.com/p-8095501.html

    Copyright@ 2017-2037 Www.163WenKu.Com  网站版权所有  |  资源地图   
    IPC备案号:蜀ICP备2021032737号  | 川公网安备 51099002000191号


    侵权投诉QQ:3464097650  资料上传QQ:3464097650
       


    【声明】本站为“文档C2C交易模式”,即用户上传的文档直接卖给(下载)用户,本站只是网络空间服务平台,本站所有原创文档下载所得归上传人所有,如您发现上传作品侵犯了您的版权,请立刻联系我们并提供证据,我们将在3个工作日内予以改正。

    163文库