340 likes | 544 Views
C 文件操作. 主要内容. 13.1 文件概述 13.2 文件类型指针 13.3 文件的打开与关闭 13.4 文件的读写 13.5 文件的定位 13.6 习题. 13.1 文件的概述. 文件的概念 指存储在外部介质 ( 如磁盘等 ) 逻辑上有联系的数据的有序集合。 分类: 从用户的角度看,分为普通文件和设备文件两种。 按数据存储方式,分为:文本文件和二进制文件。. 13.1 文件的概述.
E N D
主要内容 13.1 文件概述 13.2 文件类型指针 13.3 文件的打开与关闭 13.4 文件的读写 13.5 文件的定位 13.6 习题
13.1 文件的概述 • 文件的概念 指存储在外部介质(如磁盘等)逻辑上有联系的数据的有序集合。 • 分类: • 从用户的角度看,分为普通文件和设备文件两种。 • 按数据存储方式,分为:文本文件和二进制文件。
13.1 文件的概述 • 普通文件:一般指源文件、目标文件、可执行文件;也可以是一组待输入处理的原始数据,或者是一组输出的结果。对于源文件、目标文件、可执行程序可以称作程序文件,对输入输出数据可称作数据文件。 • 数据文件:用户数据。如未做特殊说明,本章中的文件指的是数据文件。 • 设备文件:是指与主机相联的各种外部设备,如显示器、打印机、键盘等。在操作系统中,把外部设备也看作是一个文件来进行管理,把它们的输入、输出等同于对磁盘文件的读和写。 通常把显示器定义为标准输出文件,在屏幕上显示信息就是向标准输出文件输出信息。
13.1 文件的概述 • 文本文件:也称为ASCII文件,这种文件在磁盘中存放时每个字符占用一个字节,用于存放对应的ASCII码。 十进制数5678,在内存中的存储形式为00010110 00101110(二进制形式),只占2个字节,如果按ASCII形式输出,则占4个字节。 • 二进制文件是按二进制的编码方式来存放文件的。
13.1 文件的概述 • 缓冲文件系统 文件中的数据是从内存中传送到外部介质中的,缓冲文件系统自动在内存区开辟一个缓冲区,使数据输入输出都先放到缓冲区,等缓冲区放满时,再输出到设备上。
13.1 文件的概述 • 非缓冲文件系统 系统不自动开辟确定大小的缓冲区,而是由程序员为每个文件设定一个缓冲区。新的ANSI C标准不提倡使用“非缓冲文件系统”。 • 注意 • 不要在同一个程序内混合使用这两种文件的处理方法。因为它们调用文件的方式不同,有可能相互干扰。 • 由于C对文件的操作是字节,所以可以每次读/写1个字节,则读/写512个字节就需要512次启动外设的读写操作;但是,缓冲文件系统先将要读/写的数据放入缓冲区,装满了以后再启动外部设备的读/写操作。因此,读/写512字节,只需要启动一次外设,而不是512次。
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; 表示fp是指向FILE结构的指针变量,通过fp即可找存放某个文件信息的结构变量,然后按结构变量提供的信息找到该文件,实施对文件的操作。
13.3 文件的打开与关闭 C语言程序中,文件在进行读/写操作之前要先打开,使用完毕要关闭。 • 打开文件 实际上是建立文件的各种有关信息,并使文件指针指向该文件,以便进行其它操作。 • 关闭文件 断开指针与文件之间的联系,也就禁止再对该文件进行操作。
13.3 文件的打开与关闭 • 文件打开函数fopen • 函数原型 FILE *fopen(char *filename,char *mode); • 参数说明 • filename:要打开的文件路径 • mode :打开模式 • 返回值 • 若成功,返回指向被打开文件的指针 • 若出错,返回空指针NULL(0)
13.3 文件的打开与关闭 • 文件的打开模式
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); • 参数说明 • fp:要关闭的文件指针 • 返回值 • 若成功,返回0 • 若出错,返回EOF(-1) • 不用的文件应必须关闭,防止数据破坏丢失
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.4 文件的读写 • 文件的读写函数
13.4 文件的读写 • feof函数 • 函数原型 int feof(FILE *fp); • 参数 • fp:文件指针 • 返回值 • 若文件结束,返回非零值 • 若文件尚未结束,返回0
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); • 参数 • fp:文件指针 • 返回值 • 若成功,返回输入的字符 • 若失败或文件结束,返回EOF
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函数 • 函数原型 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> 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); } fclose(fp); }
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 :要输出到文件的整数(字) • fp:文件指针 • 返回值 • 若成功,返回输出的整数(字) • 若失败,返回EOF
13.4 文件的读写 • getw函数 • 函数原型 • int getw(FILE *fp); • 参数 • fp:文件指针 • 返回值 • 若成功,返回输入的整数(字) • 若失败,返回EOF
13.4 文件的读写 • fputs函数 • 函数原型 int fputs(char *s, FILE *fp); • 返回值 • 若成功,返回输出字符个数(或最后的字符) • 若失败,返回EOF • 说明 • 字符串的结束标志'\0'不会输出到文件 • 也不会在字符串末尾自动添加换行符
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