C语言程序设计 第十三章 文件
主要内容 13.1 文件概述 13.2 文件类型指针 13.3 文件的打开与关闭 13.4 文件的读写 13.5 文件的定位 13.6 习题
13.1 文件的概述 文件的概念 指存储在外部介质(如磁盘等)逻辑上有联系的数据的有序集合。 分类: 13.1 文件的概述 文件的概念 指存储在外部介质(如磁盘等)逻辑上有联系的数据的有序集合。 分类: 从用户的角度看,分为普通文件和设备文件两种。 按数据存储方式,分为:文本文件和二进制文件。
13.1 文件的概述 普通文件:一般指源文件、目标文件、可执行文件;也可以是一组待输入处理的原始数据,或者是一组输出的结果。对于源文件、目标文件、可执行程序可以称作程序文件,对输入输出数据可称作数据文件。 数据文件:用户数据。如未做特殊说明,本章中的文件指的是数据文件。 设备文件:是指与主机相联的各种外部设备,如显示器、打印机、键盘等。在操作系统中,把外部设备也看作是一个文件来进行管理,把它们的输入、输出等同于对磁盘文件的读和写。 通常把显示器定义为标准输出文件,在屏幕上显示信息就是向标准输出文件输出信息。
13.1 文件的概述 文本文件:也称为ASCII文件,这种文件在磁盘中存放时每个字符占用一个字节,用于存放对应的ASCII码。 13.1 文件的概述 文本文件:也称为ASCII文件,这种文件在磁盘中存放时每个字符占用一个字节,用于存放对应的ASCII码。 十进制数5678,在内存中的存储形式为00010110 00101110(二进制形式),只占2个字节,如果按ASCII形式输出,则占4个字节。 二进制文件是按二进制的编码方式来存放文件的。
13.1 文件的概述 缓冲文件系统 文件中的数据是从内存中传送到外部介质中的,缓冲文件系统自动在内存区开辟一个缓冲区,使数据输入输出都先放到缓冲区,等缓冲区放满时,再输出到设备上。
13.1 文件的概述 非缓冲文件系统 系统不自动开辟确定大小的缓冲区,而是由程序员为每个文件设定一个缓冲区。新的ANSI C标准不提倡使用“非缓冲文件系统”。 注意 不要在同一个程序内混合使用这两种文件的处理方法。因为它们调用文件的方式不同,有可能相互干扰。 由于C对文件的操作是字节,所以可以每次读/写1个字节,则读/写512个字节就需要512次启动外设的读写操作;但是,缓冲文件系统先将要读/写的数据放入缓冲区,装满了以后再启动外部设备的读/写操作。因此,读/写512字节,只需要启动一次外设,而不是512次。
13.2 文件类型指针 文件类型指针 是指向描述文件信息结构体的结构体变量,用于文件操作。 13.2 文件类型指针 文件类型指针 是指向描述文件信息结构体的结构体变量,用于文件操作。 在C语言中,对普通数据文件的所有操作都必须依靠文件类型指针来完成。要想对文件进行操作,首先必须将想要操作的数据文件与文件指针建立联系,然后通过这些文件指针来操作相应的文件。 C语言程序可同时处理多个文件,为了对每个文件进行有效的管理,就需要开辟一个“文件信息描述区”,记录文件的当前状态(文件名、文件大小等)。该信息描述区是用一个结构变量来命名和记录实现的。该结构变量名叫文件结构变量。文件结构变量的类型由系统定义,并取名为FILE。它通常被存放在<stdio.h>头文件中。
13.2 文件类型指针 每一个要操作的文件,都必须定义一个指针变量,并使它指向该文件结构变量,该指针叫文件类型指针。于是可通过该指针找到被操作文件的描述信息,进而对其进行读写。 FILE 结构类型的格式,各个编译系统有微小的区别,大致如下: typedef struct { short level; /*缓冲区“满”或“空”的程度 */ unsigned int flags; /* 文件代号*/ char fd; /* 文件描述符*/ unsigned char hold; /* 如无缓冲区不读取字符*/ short bsize; /*缓冲区的大小*/ unsigned char *buffer; /*数据缓冲区首地址*/ unsigned char *curp; /* 指针当前位置(下一个待处理字节地址)*/ unsigned int istemp; /* 临时文件指示器*/ short token; /* 用于有效性检查*/ } FILE; /* 自定义的类型名*/
13.2 文件类型指针 定义说明文件指针格式 FILE* 指针变量标识符; 例如:FILE *fp; 13.2 文件类型指针 定义说明文件指针格式 FILE* 指针变量标识符; 例如:FILE *fp; 表示fp是指向FILE结构的指针变量,通过fp即可找存放某个文件信息的结构变量,然后按结构变量提供的信息找到该文件,实施对文件的操作。
13.3 文件的打开与关闭 C语言程序中,文件在进行读/写操作之前要先打开,使用完毕要关闭。 打开文件 13.3 文件的打开与关闭 C语言程序中,文件在进行读/写操作之前要先打开,使用完毕要关闭。 打开文件 实际上是建立文件的各种有关信息,并使文件指针指向该文件,以便进行其它操作。 关闭文件 断开指针与文件之间的联系,也就禁止再对该文件进行操作。
13.3 文件的打开与关闭 文件打开函数fopen 函数原型 FILE *fopen(char *filename,char *mode); 13.3 文件的打开与关闭 文件打开函数fopen 函数原型 FILE *fopen(char *filename,char *mode); 参数说明 filename:要打开的文件路径 mode :打开模式 返回值 若成功,返回指向被打开文件的指针 若出错,返回空指针NULL(0)
13.3 文件的打开与关闭 r w a r+ w+ a+ t b 文件的打开模式 打开模式 描 述 只读,打开已有文件,不能写 13.3 文件的打开与关闭 文件的打开模式 打开模式 描 述 r 只读,打开已有文件,不能写 w 只写,创建或打开,覆盖已有文件 a 追加,创建或打开,在已有文件末尾追加 r+ 读写,打开已有文件 w+ 读写,创建或打开,覆盖已有文件 a+ 读写,创建或打开,在已有文件末尾追加 t 按文本方式打开 (缺省) b 按二进制方式打开
13.3 文件的打开与关闭 文件的打开举例 FILE *fp1, *fp2, *fp3; 13.3 文件的打开与关闭 文件的打开举例 FILE *fp1, *fp2, *fp3; char filename[ ]="file3.dat"; /* 以文本只读方式打开file1 */ if (!(fp1=fopen("file1", "r"))) { printf("Cannot Open This File!\n"); exit(0); /* 退出程序 */ } fp2=fopen("C:\\HOME\\FILE2.TXT", "rb+"); /* 以二进制读写方式打开FILE2.TXT */ fp3=fopen(filename, "a+b"); /* 以二进制读写方式打开file3.dat */
13.3 文件的打开与关闭 文件关闭函数 (fclose) 函数原型 int fclose(FILE *fp); 参数说明 13.3 文件的打开与关闭 文件关闭函数 (fclose) 函数原型 int fclose(FILE *fp); 参数说明 fp:要关闭的文件指针 返回值 若成功,返回0 若出错,返回EOF(-1) 不用的文件应必须关闭,防止数据破坏丢失
13.3 文件的打开与关闭 文件的关闭举例 FILE *fp; char file[]="D:\\USER\\STUDENTS.DAT"; 13.3 文件的打开与关闭 文件的关闭举例 FILE *fp; char file[]="D:\\USER\\STUDENTS.DAT"; if (!(fp=fopen(file, "rb+"))) { printf("Open file %s error!\n", file); exit(0); } ... ... fclose(fp);
13.3 文件的打开与关闭 C语言程序中,文件操作顺序为:打开-读/写-关闭。 文件操作程序的编写分以下几步: 定义文件指针; 13.3 文件的打开与关闭 C语言程序中,文件操作顺序为:打开-读/写-关闭。 文件操作程序的编写分以下几步: 定义文件指针; 打开文件,并判断是否成功打开,若打开文件失败,程序退出运行状态; 对文件进行读写等操作; 关闭文件。
13.4 文件的读写 文件的读写函数 函数 功能 fputc 输出字符 fprintf 格式化输出 fgetc 输入字符 fscanf 13.4 文件的读写 文件的读写函数 函数 功能 fputc 输出字符 fprintf 格式化输出 fgetc 输入字符 fscanf 格式化输入 putc putw 输出一个字 getc getw 输入一个字 fwrite 输出数据块 fputs 输出字符串 fread 输入数据块 fgets 输入字符串
13.4 文件的读写 feof函数 函数原型 int feof(FILE *fp); 参数 fp:文件指针 返回值 若文件结束,返回非零值 13.4 文件的读写 feof函数 函数原型 int feof(FILE *fp); 参数 fp:文件指针 返回值 若文件结束,返回非零值 若文件尚未结束,返回0
13.4 文件的读写 fputc/putc函数 函数原型 int fputc(int c, FILE *fp); 13.4 文件的读写 fputc/putc函数 函数原型 int fputc(int c, FILE *fp); int putc(int c, FILE *fp); 参数 c :要输出到文件的字符 fp:文件指针 返回值 若成功,返回输出的字符 若失败,返回EOF
13.4 文件的读写 fgetc/getc函数 函数原型 int fgetc(FILE *fp); int getc(FILE *fp); 13.4 文件的读写 fgetc/getc函数 函数原型 int fgetc(FILE *fp); int getc(FILE *fp); 参数 fp:文件指针 返回值 若成功,返回输入的字符 若失败或文件结束,返回EOF
13.4 文件的读写 举例:将file_in.txt的文件内容读出并写入到file_out.txt文件中 13.4 文件的读写 举例:将file_in.txt的文件内容读出并写入到file_out.txt文件中 #include <stdio.h> void main() { FILE *fp1, *fp2; char c; fp1 = fopen("file_in.txt", "r"); fp2 = fopen("file_out.txt", "w"); while(!feof(fp1)) { c = fgetc(fp1); fputc(c, fp2); } fclose(fp1); fclose(fp2);
13.4 文件的读写 fwrite和fread函数 函数原型 13.4 文件的读写 fwrite和fread函数 函数原型 size_t fwrite(void *buffer, size_t size, size_t count, FILE *fp); size_t fread (void *buffer, size_t size, size_t count, FILE *fp); 参数 buffer:要读/写的数据块地址 size :要读/写的每个数据项的字节数 count :要读/写的数据项数量 fp :文件指针 返回值 若成功,返回实际读/写的数据项数量 若失败,一般返回0
13.4 文件的读写 fwrite和fread函数举例 #include<stdio.h> 13.4 文件的读写 fwrite和fread函数举例 #include<stdio.h> struct student{ int no,age; } st; void main(){ int i; FILE *fp; fp=fopen("c:\\rr.dat","wb"); for(i=0;i<3;i++){ scanf("%d,%d", &st.no,&st.age); fwrite(&st,sizeof(st),1,fp); } fclose(fp); fp=fopen("c:\\rr.dat","rb"); while(!feof(fp)) { fread(&st,sizeof(st),1,fp); if(!feof(fp))printf("no:%d,age,%d\n",st.no,st.age);
13.4 文件的读写 fprintf和fscanf函数 函数原型 13.4 文件的读写 fprintf和fscanf函数 函数原型 int fscanf(FILE *fp, char *format[,address,...]); int fprintf(FILE *fp,char *format[,argument,...]); 说明 与printf和scanf函数类似 从文件输入或输出到文件
13.4 文件的读写 putw函数 函数原型 int putw(int w, FILE *fp); 参数 w :要输出到文件的整数(字) 13.4 文件的读写 putw函数 函数原型 int putw(int w, FILE *fp); 参数 w :要输出到文件的整数(字) fp:文件指针 返回值 若成功,返回输出的整数(字) 若失败,返回EOF
13.4 文件的读写 getw函数 函数原型 int getw(FILE *fp); 参数 fp:文件指针 返回值 13.4 文件的读写 getw函数 函数原型 int getw(FILE *fp); 参数 fp:文件指针 返回值 若成功,返回输入的整数(字) 若失败,返回EOF
13.4 文件的读写 fputs函数 函数原型 int fputs(char *s, FILE *fp); 返回值 13.4 文件的读写 fputs函数 函数原型 int fputs(char *s, FILE *fp); 返回值 若成功,返回输出字符个数(或最后的字符) 若失败,返回EOF 说明 字符串的结束标志'\0'不会输出到文件 也不会在字符串末尾自动添加换行符
13.4 文件的读写 fgets函数 函数原型 char *fgets(char *s, int n, FILE *fp); 返回值 13.4 文件的读写 fgets函数 函数原型 char *fgets(char *s, int n, FILE *fp); 返回值 若成功,返回s首地址;若失败,返回NULL 说明 从fp输入字符串到s中 输入n-1个字符,或遇到换行符或EOF为止 读完后自动在字符串末尾添加'\0'
13.5 文件的定位 文件位置指针 位置指针指向当前读写的位置 每次读写文件,位置指针都会相应移动 可以通过相关函数强制修改位置指针 rewind函数 fseek函数 ftell函数
13.5 文件的定位 正常读写过程中,文件指针自动下移,移到下一次应读写的位置。也可以使用文件指针移动函数, 人为移动文件指针: void rewind(FILE *fp) //使文件指针指向文件开头 int fseek(FILE +fp,long offset,int base); //从base移动offset个字节,正值向后移,负值向前移,移动成功返回1,否则返回非0 base值可选项: SEEK_SET(文件头) SEEK_CUR(当前指针位置) SEEK_END(文件尾) 辅助函数:long ftell(FILE *fp);获得文件指针当前位置
13.5 文件的定位 rewind函数 函数原型 void rewind(FILE *fp); 参数 fp:文件指针 功能 使文件位置指针重新返回文件开头
13.5 文件的定位 fseek函数 函数原型:int fseek(FILE *fp, long offset,int whence); 参数 fp :文件指针 offset:偏移量 whence:起始位置 功能:随机改变文件的位置指针 起始位置 SEEK_SET(0):文件开始 SEEK_CUR(1):文件当前位置 SEEK_END(2):文件末尾 举例 fseek(fp, 100L, SEEK_SET); fseek(fp, -10L, SEEK_CUR); fseek(fp, -20L, SEEK_END);
13.5 文件的定位 ftell函数 函数原型 long ftell(FILE *fp); 参数 fp:文件指针 返回值 若成功,返回当前文件指针位置 若出错,返回-1L