谭浩强C语言PPT(11).ppt_第1页
谭浩强C语言PPT(11).ppt_第2页
谭浩强C语言PPT(11).ppt_第3页
谭浩强C语言PPT(11).ppt_第4页
谭浩强C语言PPT(11).ppt_第5页
已阅读5页,还剩17页未读 继续免费阅读

下载本文档

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

文档简介

1、C语言程序设计,第12章 文 件,电子邮箱:,主讲:张驰 淮安信息学院计算机科学与工程系,第12章 文 件,12.1 C文件概述,文件(file)是程序设计中一个重要的概念。 “文件”一般指存储在外部介质上数据的集合。 C语言把文件看作是一个字符(字节)的序列,即由一个一个字符(字节)的数据顺序组成。根据数据的组织形式,可分为ASCII文件和二进制文件。 ASCII文件又称文本(text)文件,它的每一个字节放一个ASCII代码,代表一个字符;二进制文件是把内存中的数据按其在内存中的存储形式原样输出到磁盘上存放。 例如:如果有一个整数10000,在内存中占2个字节,如果按ASCII码形式输出,

2、则占5个字节,而按二进制形式输出,在磁盘上只占2个字节,见图所示。 (int占2个字节、10000有5个符号,用ASCII码表示要用5个字节),用ASCII码形式输出与字符一一对应,一个字节代表一个字符,因而便于对字符进行逐个处理,也便于输出字符。但一般占存储空间较多,而且要花费转换时间(二进制形式与ASCII码间的转换)。 用二进制形式输出数值,可以节省外存空间和转换时间,但一个字节并不对应一个字符,不能直接输出字符形式。一般中间结果数据需要暂时保存在外存上以后又需要输入到内存的,常用二进制文件保存。,一个C文件是一个字节流或二进制流,它把数据看作是一连串的字符(字节),而不考虑记录的界限。

3、换句话说,C语言中文件并不是由记录(record)组成的。在C语言中对文件的存取是以字符(字节)为单位的,输入输出的数据流的开始和结束仅受程序控制而不受物理符号(如回车换行符)控制,我们把这种文件称为流式文件。 C语言允许对文件存取一个字符,这就增加了处理的灵活性。,在过去使用的C版本(如UNIX系统下使用的C)有两种对文件的处理方法:一种叫“缓冲文件系统”,一种叫“非缓冲文件系统”。 “缓冲文件系统”是指系统自动地在内存区为每一个正在使用的文件名开辟一个缓冲区。从内存向磁盘输出数据必须先送到内存中的缓冲区,装满缓冲区后才一起送到磁盘去。如果从磁盘向内存读入数据,则一次从磁盘文件将一批数据输入

4、到内存缓冲区(充满缓冲区),然后再从缓冲区逐个地将数据送到程序数据区(给程序变量)。缓冲区的大小由各个具体的C版本确定,一般为512字节。 “非缓冲文件系统”是指系统不自动开辟确定大小的缓冲区,而由程序为每个文件设定缓冲区。,12.2 文件类型指针,在UNIX系统下,用缓冲文件系统来处理文本文件,用非缓冲文件系统处理二进制文件。用缓冲文件系统进行的输入输出又称为高级(或高层)磁盘输入输出(高层I/O),用非缓冲文件系统进行的输入输出又称为低级(低层)输入输出系统。 ANSI C标准决定不采用非缓冲文件系统,而只采用缓冲文件系统。即既用缓冲文件系统处理文本文件,也用它来处理二进制文件。也就是将缓

5、冲文件系统扩充为可以处理二进制文件。 在C语言中,没有输入输出语句,对文件的读写都是用库函数来实现的。ANSI规定了标准输入输出函数,用它们对文件进行读写。,文件指针:每个被使用的文件都在内存中开辟一个区,用来存放文件的有关信息(如文件的名字、文件状态及文件当前位置等)。这些信息是保存在一个结构体变量中的。该结构体类型是由系统定义的,取名为FILE。,Turbo C在stdio.h文件中有以下的文件类型声明: typedefstruct short level; /*缓冲区“满”或“空”的程度*/ unsigned flags; /*文件状态标志*/ char fd; /*文件描述符*/ un

6、signed char hold; /*如无缓冲区不读取字符*/ short bsize; /*缓冲区的大小*/ unsigned char *buffer; /*数据缓冲区的位置*/ unsigned char *curp; /*指针,当前的指向*/ unsigned istemp; /*临时文件,指示器*/ short token; /*用于有效性检查*/ FILE; /*文件类型*/,有了结构体FILE类型之后,可以用它来定义若干个FILE类型的变量,以便存放若干个文件的信息。,例如:可以定义以下FILE类型的数组。 FILEf5; /*定义结构体数组f,用来存放5个文件的信息*/ 例如

7、:可以定义文件型指针变量。 FILE*fp;,通过文件指针变量能够找到与它相关的文件。,12.3 文件的打开与关闭,对文件读写之前应该“打开”该文件,在使用结束之后应“关闭”该文件。,12.3.1 文件的打开(fopen函数) fopen函数的调用方式通常为: FILE*fp; fp=fopen(文件名,使用文件方式); 例如:FILE *fp; fp=fopen(a1,r); /*双引号*/ fopen函数带回指向a1文件的指针并赋给fp,这样fp就和文件a1相联系了。或者说,fp指向a1文件。 可以看出,在打开一个文件时,通知给编译系统以下3个信息: 需要打开的文件名。 使用文件的方式。(

8、见下表) 让哪一个指针变量指向被打开的文件。,说明: 如果不能实现“打开”的任务,fopen函数将会带回一个出错信息。 此时fopen函数带回一个空指针值NULL (NULL在stdio.h文件中已被定义为0) 常用下面的方法打开一个文件: if(fp=fopen(file1“,r)=NULL) printf(cannot open this filen); exit(0); /* 关闭所有文件,终止正在调用的过程*/ 在程序开始运行时,系统自动打开3个标准文件:标准输入、标准输出、标准出错输出。通常这3个文件都与终端相联系。以前我们所用到的从终端输入或输出都不需要打开终端文件。系统自动定义了

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

10、闭文件将会丢失数据。因为,在向文件写数据时,是先将数据输到缓冲区,待缓冲区充满后才正式输出给文件。如果当数据未充满缓冲区而程序结束运行,就会将缓冲区中的数据丢失。用fclose函数关闭文件,可以避免这个问题,它先把缓冲区中的数据输出到磁盘文件,然后才释放文件指针变量。 fclose函数也带回一个值,当顺利地执行了关闭操作,则返回值为0;否则返回EOF(-1)。可以用ferror函数来测试。,12.4 文件的读写 文件打开之后,就可以对它进行读写了。,12.4.1fputc函数和fgetc函数 (putc函数和getc函数) 1fputc函数:把一个字符写到磁盘文件上去。 其一般调用形式为: f

11、putc(ch,fp); 其中:ch是要输出的字符,可以是一个字符常量,也可以是一个字符变量; fp是文件指针变量。 fputc(ch,fp)函数的作用是将字符(ch的值)输出到fp所指向的文件中去。 fputc函数也带回一个值:如果输出成功则返回值就是输出的字符;如果输出失败,则返回一个EOF(-1)。EOF是在stdio.h文件中定义的符号常量,值为-1。 putchar是从fputc函数派生出来的。putchar(c)是stdio.h文件中定义的宏: #defineputchar(c)fputc(c,stdout) stdout是系统定义的文件指针变量,它与终端输出相连。fputc(c,

12、stdout)的作用是将c的值输出到终端。用宏putchar(c)比写fputc(c,stdout)简单一些,从用户的角度,可以把putchar(c)看作函数而不必严格地称它为宏。,2. fgetc函数:从指定的文件读入一个字符。 fgetc函数的调用形式为: ch=fgetc(fp); 其中:fp为文件型指针变量,ch为字符变量。 fgetc函数带回一个字符,赋给ch。 如果在执行fgetc函数读字符时遇到文件结束符,函数返回一个文件结束标志EOF(-1)。 如果想从一个磁盘文件顺序读入字符并在屏幕上显示出来,可以: ch=fgetc(fp); while(ch!=EOF) putchar(

13、ch); ch=fgetc(fp); ,注意: EOF不是可输出字符,因此不能在屏幕上显示。由于字符的ASCII码不可能出现-1,因此EOF定义为-1是合适的。当读入的字符值等于-1(即EOF)时,表示读入的已不是正常的字符而是文件结束符(但以上只适用于读文本文件的情况) 现在ANSI C已允许用缓冲文件系统处理二进制文件,而读入某一个字节中的二进制数据的值有可能是-1,而这又恰好是EOF的值。这就出现了需要读入有用数据而却被处理为“文件结束”的情况。为了解决这个问题,ANSI C提供一个feof函数来判断文件是否真的结束。 feof(fp)用来测试fp所指向的文件当前状态是否“文件结束”。如

14、果是文件结束,函数feof(fp)的值为1(真),否则为0(假)。 如果想顺序读入一个二进制文件中的数据,可以用 while(!feof(fp) c=fgetc(fp); 这种方法也适用于文本文件。,为了书写方便,系统把fputc和fgetc定义为宏名putc和getc #define putc(ch,fp) fputc(ch,fp) #define getc(fp) fgetc(fp) 这是在stdio.h中定义的。用putc和fputc,用getc和fgetc是一样的。,12.4.2 fread函数和fwrite函数 (一般是二进制文件,打开任何类型的数据) 用来读写一个数据块。,它们的一

15、般调用形式为: fread(buffer,size,count,fp); fwrite(buffer,size,count,fp); 其中:buffer是一个指针(地址)。 对fread来说,它是读入数据的存放地址(起始地址)。 对fwrite来说,是要输出数据的起始地址。 size:要读写的字节数。 count:要进行读写多少个size字节的数据项。 fp:文件型指针。,如果文件以二进制形式打开,用fread和fwrite函数就可以读写任何类型的信息。 如果fread或fwrite调用成功,则函数返回值为count的值,即输入或输出数据项的完整个数。,如:fread(f,4,2,fp); /

16、*从fp所指文件读2次(每次4个字节)数据,存到数组f中*/ 其中f是实型数组名,一个实型变量占4个字节。 如:有一个如下的结构体类型 structstudent_type char name10; int num; int age; char addr30; stud40; 假设学生的数据已存放在磁盘文件中,可以用下面的for语句和fread函数读入40个学生的数据: for(i=0;i40;i+) fread(,12.4.3 fprintf函数和fscanf函数 文本文件 printf函数、scanf函数读写对象是终端。 fprintf函数、fscanf函数的读写对象是磁盘文件。 它们的一

17、般调用方式为: fprintf(文件指针,格式字符串,输出表列); (输出到磁盘文件上) fscanf(文件指针,格式字符串,输入表列); (从磁盘文件上读入) 例如:fprintf(fp,”%d,%6.2f”,i,t); 将两个值i、t按指定的格式输出到fp所指向的磁盘文件上 例如:fscanf(fp,”%d,%6.2f”, 从fp所指向的磁盘文件上按指定的格式读两个值i、t 用fprintf和fscanf函数对磁盘文件读写,使用方便,容易理解,但由于在输入时要将ASCII码转换为二进制形式,在输出时又要将二进制形式转换成字符,花费时间比较多。因此,在内存与磁盘频繁交换数据的情况下,最好不用

18、fprintf和fscanf函数,而用fread和fwrite函数。,12.4.4 其他读写函数 1putw和getw函数 一个字(整数) 用来对磁盘文件读写一个字(整数)。 例如:putw(10,fp); /*将整数10输出到fp指向的文件*/ 例如:i=getw(fp); /*从磁盘文件读一个整数到内存,赋给整型变量i*/ 2读写其他类型数据 自己定义 3fgets函数和fputs函数 一个字符串 fgets的作用是从指定文件读入一个字符串。 如:fgets(str,n,fp); 其中:n是要得到的字符个数,包括最后0在内,str是字符数组*/ 若在读完n-1个字符之前遇到换行符或EOF,

19、读入即结束。 fgets函数返回值为str的首地址。 fputs函数的作用是向指定的文件输出一个字符串。 如:fputs(China,fp); /*把字符串“China”输出到fp指向的文件*/ 其中:fputs函数中第一个参数可以是字符串常量、字符数组名或字符 型指针。字符串末尾的0 不输出。 若输出成功,函数值为0;失败时,为EOF。 gets和puts函数 fgets和fputs函数以指定的文件作为读写对象。,12.5 文件的定位,文件中有一个位置指针,指向当前读写的位置。如果顺序读写一个文件,每次读写一个字符,则读写完一个字符后,该位置指针自动移动指向下一个字符位置。如果想改变这样的规

20、律,强制使位置指针指向其他指定的位置,可以用有关函数。 12.5.1 rewind函数 返回文件头 rewind函数的作用是使位置指针重新返回文件的开头。 此函数没有返回值。 如:rewind(fp); 12.5.2 fseek函数和随机读写 一般是二进制文件 对流式文件可以进行顺序读写,也可以进行随机读写。关键在于控制文件的位置指针,如果位置指针是按字节位置顺序移动的,就是顺序读写;如果能将位置指针按需要移动到任意位置,就可以实现随机读写。 用fseek函数可以实现改变文件的位置指针。 fseek函数的调用形式为: fseek(文件类型指针,位移量,起始点) 其中:“起始点”用0、1、2代替,0“文件开始”,1“当前位置”,2“文件末尾”。 “位移量”指以“起始点”为基点,向前移动的字节数。 ANSI C和大多数C版本要求位移量是long型数据。,fseek函数一般用于二进制文件,因为文本文件要发生字符转换,计算位置时往往会发生混乱。 下面是fseek函数调用的几个例子:(L表示long型) fseek(fp,100L,0); 将位置指针移到离文件头100个字节处 fseek(fp,5

温馨提示

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

评论

0/150

提交评论