第9章 文件 本章导读 本章主要知识点 《 C语言程序设计》 (Visual C++ 6.0环境) 第9章 文件 本章导读 文件是程序设计中极为重要的一个概念,文件一般指存储在外部介质上的数据的集合。通过文件可以大批量处理数据,可以长时间的将信息存储起来。本章通过文件操作实例分析着手,使读者首先对文件的操作过程有一个初步的了解,明白文件操作的重要性,进而再深入的学习C语言有关文件的操作 。 《 C语言程序设计》 (Visual C++ 6.0环境) 本章主要知识点 (1)文件操作的C程序实例 (2)文件的打开与关闭 (3)文件的读写和定位 (4)文件出错的检测 返回本书目录
第9章 文件 9.1 文件操作的C程序实例 9.2 文件的打开与关闭 9.3 文件的读写 9.4 文件的定位 9.5 文件出错的检测 第9章 文件 《 C语言程序设计》 (Visual C++ 6.0环境) 9.1 文件操作的C程序实例 9.2 文件的打开与关闭 9.3 文件的读写 9.4 文件的定位 9.5 文件出错的检测 9.6 综合实训 返回本章导读
9.1 文件操作的C程序实例 9.1.1 文件操作的C程序实例 9.1.2 C文件概述 9.1.3 文件类型指针 《 C语言程序设计》 (Visual C++ 6.0环境) 9.1.1 文件操作的C程序实例 9.1.2 C文件概述 9.1.3 文件类型指针 返回本章目录
9.1.1 文件操作的C程序实例 1. C程序实例(1) 2. C程序实例(2) 3. C程序实例(3) 《 C语言程序设计》 (Visual C++ 6.0环境) 1. C程序实例(1) 2. C程序实例(2) 3. C程序实例(3) 返回本节目录
9.1.1 文件操作的C程序实例 1.C程序实例1 《 C语言程序设计》 (Visual C++ 6.0环境) 【例9.1】读出文件file.txt中的字符。 程序文件名为l9_1.cpp。 1) #include "stdio.h" #include <stdlib.h> void main() { char ch; /*定义一个字符变量ch*/ FILE *fp; /*定义一个文件类型的指针变量fp*/ fp=fopen("file.txt","r");/*打开文本文件file*/ if(fp==NULL) /*打开文件失败*/ { printf("cannot open this file\n"); exit(0); } 返回本节目录
9.1.1 文件操作的C程序实例 《 C语言程序设计》 (Visual C++ 6.0环境) ch=fgetc(fp); /*读出文件中的字符并赋予变量ch*/ while(ch!=EOF) /*判断文件是否结束*/ { putchar(ch); /*输出从文件中读出的字符*/ ch=fgetc(fp); /*读出文件中的字符并赋予变量ch*/ } fclose(fp); /*关闭文件*/ 《 C语言程序设计》 (Visual C++ 6.0环境) 建立文本文件,在文件中输入一些文字,保存文件名为file,然后与程序文件放在同一目录下。如右图所示: 返回本节目录
9.1.1 文件操作的C程序实例 《 C语言程序设计》 (Visual C++ 6.0环境) 程序执行结果为: 从文件file中读出的文字 返回本节目录
9.1.1 文件操作的C程序实例 2.C程序实例2 《 C语言程序设计》 (Visual C++ 6.0环境) 【例9.2】将用户从键盘输入的用户名和密码写到文件user.x中。 程序文件名为l9_2.cpp。 #include "stdio.h" #include <stdlib.h> struct userinfo /*定义结构体*/ { char username[10]; char password[12]; }stu; void main() { FILE *fp; /*定义文件指针fp*/ fp=fopen("user.x","wb"); /*以二进制方式打开文件user.x*/ if(fp==NULL) /*打开文件失败*/ 返回本节目录
9.1.1 文件操作的C程序实例 《 C语言程序设计》 (Visual C++ 6.0环境) { printf("cannot open this file\n"); exit(0); } printf("Please input your username:"); scanf("%s",&stu.username); printf("\nPlease input your password:"); scanf("%s",&stu.password); fwrite(&stu,sizeof(userinfo),1,fp); /*将用户输入的信息写入文件*/ fclose(fp); /*关闭文件*/ 例如用户根据提示信息输入如下: Please input your username:student Please input your password:12345678 则执行结果为先在程序文件的目录下建立文件user.x,然后将字符串 “student”和“12345678”写入该文件。 《 C语言程序设计》 (Visual C++ 6.0环境) 返回本节目录
9.1.1 文件操作的C程序实例 3.C程序实例3 《 C语言程序设计》 (Visual C++ 6.0环境) 【例9.3】从文件user.x中读取用户名和密码。 程序文件名为l9_3.cpp。 #include "stdio.h" #include <stdlib.h> struct userinfo /*定义结构体*/ { char username[10]; char password[12]; }stu; 返回本节目录
9.1.1 文件操作的C程序实例 《 C语言程序设计》 (Visual C++ 6.0环境) void main() { FILE *fp; /*定义文件类型指针fp*/ fp=fopen(“user.x”,“rb”); /*以二进制只读方式打开文件user.x*/ if(fp==NULL) { printf("cannot open this file\n"); exit(0); } fread(&stu,sizeof(userinfo),1,fp); /*读出文件中的数据*/ printf("your username:%s\n",stu.username); printf("your password:%s\n",stu.password); fclose(fp); /*关闭文件*/ 《 C语言程序设计》 (Visual C++ 6.0环境) 假如user.x中的数据是实例2所输入的信息,则输出结果为: your username:student your password:12345678 返回本节目录
9.1.2 C文件概述 《 C语言程序设计》 (Visual C++ 6.0环境) C语言把磁盘文件看作是字符(或字节)的序列,根据数据的组织形式(存储信息的形式),文件可分为ASCⅡ码文件和二进制文件。ASCⅡ码文件又称为文本文件,该文件是由一个个字符组成,每一个字节存放一个ASCⅡ码,代表一个字符。二进制文件是把内存中的数据按其在内存中的存储形式原样放入磁盘存放。 例如,现有一个整数1234,如果按ASCⅡ码形式存入文件,要占4个字节,其存储形式如下: 《 C语言程序设计》 (Visual C++ 6.0环境) 返回本节目录
9.1.2 C文件概述 00000100 11010010 《 C语言程序设计》 (Visual C++ 6.0环境) 如果按二进制形式存入文件,则只占2个字节,其存储形式 与内存中的存储形式相同,如下: 《 C语言程序设计》 (Visual C++ 6.0环境) 00000100 11010010 由以上举例不难看出用ASCⅡ码形式存入文件时一个字节代表一个字符,因而便于对字符进行逐个处理,也便于输出,但一般占存储空间较大,而且要花费二进制形式与ASCⅡ码之间的转换时间。用二进制形式存入文件则可以节省外存空间和转换时间,但一个字节并不对应一个字符,所以如果在屏幕上显示经常显示的是乱码。 返回本节目录
9.1.3 文件类型指针 《 C语言程序设计》 (Visual C++ 6.0环境) 9.1.3 文件类型指针 C语言程序可以同时处理多个文件,为了对每一个文件进行有效的管理,在打开一个文件时,系统会自动地在内存中开辟一个区,用来存放文件的有关信息(如文件名、文件状态等)。这些信息保存在一个结构体变量中,该结构体是由系统定义的,取名为FILE。FILE定义在头文件stdio.h中 。 对每一个要进行操作的文件,都需要定义一个指向FILE类型结构体的指针变量,该指针称为文件类型指针,文件类型指针的定义方法如下: FILE *指针变量; 如:FILE *fp; fp是一个指向FILE类型结构体的指针变量。当fp和某个文件建立关联之后,通过fp 即可找到存放该文件信息的结构变量,然后按结构变量提供的信息找到该文件, 实施对文件的操作。 《 C语言程序设计》 (Visual C++ 6.0环境) 返回本节目录
9.2 文件的打开与关闭 9.2.1 文件打开函数fopen() 9.2.2 文件关闭函数fclose() 9.2 文件的打开与关闭 《 C语言程序设计》 (Visual C++ 6.0环境) 9.2.1 文件打开函数fopen() 9.2.2 文件关闭函数fclose() 返回本章目录
9.2.1 文件打开函数fopen() 《 C语言程序设计》 (Visual C++ 6.0环境) 在使用一个文件之前,必须先打开它,然后才能对它进行读写操作,从9.1.1的C程序实例我们也能看出,每个程序都用到了fopen函数,该函数的功能就是用来打开一个文件。函数fopen的使用格式为: 《 C语言程序设计》 (Visual C++ 6.0环境) FILE *文件指针变量; 文件指针变量=fopen(“文件名”, “文件使用方式”); fopen函数的作用是以指定的方式打开指定文件。如果文件打开成功,返回一个文件类型指针,如果文件打开失败,则返回一个空指针NULL。 “文件名”指要打开文件的名称。 “文件使用方式”指文件的类型和操作要求。如下表所示: 返回本节目录
9.2.1 文件打开函数fopen() 《 C语言程序设计》 (Visual C++ 6.0环境) 返回本节目录
9.2.1 文件打开函数fopen() 《 C语言程序设计》 (Visual C++ 6.0环境) 由于文件是独立于程序之外不易被控制的,所以调用文件是程序中最易出错的地方。打开文件也是如此,当打开文件出错时,函数fopen会返回一个空指针NULL,出错原因可能是以“r”方式打开一个不存在的文件,或者是磁盘已满等。一旦文件打开出错,后边的程序也将无法执行,好的习惯是先检查打开文件时是否出错,如果有错则提示给用户,并终止程序的执行,等用户检查出错误,修改后再运行该程序。所以通常打开文件的方法是: 《 C语言程序设计》 (Visual C++ 6.0环境) FILE *文件指针变量; 文件指针变量=fopen(“文件名”, “文件使用方式”); If(文件指针变量= =NULL) { printf(“cannot open this file\n”); exit(0); } 返回本节目录
9.2.2 文件关闭函数fclose() 《 C语言程序设计》 (Visual C++ 6.0环境) fclose(文件指针变量); fclose用来关闭文件指针变量所指向的文件。该函数如果调用成功,返回数值0,否则返回一个非零值。 如:fclose(fp); 关闭文件后,文件类型指针变量将不再指向和它所关联的文件,此后不能再通过该指针对原来与其关联的文件进行读写操作,除非再次打开该文件,使该指针变量重新指向该文件。 《 C语言程序设计》 (Visual C++ 6.0环境) 返回本节目录
9.3 文件的读写 9.3.1 单个字符读写函数 9.3.2 字符串读写函数 9.3.3 数据块读写函数 9.3.4 格式化读写函数 9.3 文件的读写 《 C语言程序设计》 (Visual C++ 6.0环境) 9.3.1 单个字符读写函数 9.3.2 字符串读写函数 9.3.3 数据块读写函数 9.3.4 格式化读写函数 9.3.5 整数读写函数 返回本章目录
9.3.1 单个字符读写函数 1.读字符函数fgetc() 《 C语言程序设计》 (Visual C++ 6.0环境) 9.3.1 单个字符读写函数 1.读字符函数fgetc() 《 C语言程序设计》 (Visual C++ 6.0环境) 该函数的使用方法为: 字符变量=fgetc(文件指针变量); 函数fgetc的作用是从文件指针变量指向的文件中读取一个字符。该函数如果调用成功,返回读出的字符,文件结束或出错时返回EOF(-1) 如:ch=fgetc(fp); 其中,ch是字符变量,fp为文件指针变量,fgetc函数将从fp指向的文件中读出一个字符并赋给变量ch。 在fgetc()函数调用中,读取的文件必须是以读或读写方式打开。 返回本节目录
9.3.1 单个字符读写函数 2.写字符函数fputc() 《 C语言程序设计》 (Visual C++ 6.0环境) 9.3.1 单个字符读写函数 2.写字符函数fputc() 《 C语言程序设计》 (Visual C++ 6.0环境) 该函数的一般格式为: fputc(ch,文件指针变量); fputc函数的作用是将ch所对应的一个字符写入到文件指针变量所指向的文件中去。 ch是要写入到文件中的字符,它可以是一个字符常量,也可以是一个字符变量。如果函数调用成功返回所写字符的ASCII码值,出错时返回EOF。 如:fputc(“a”,fp); 其执行结果是将字符a写入到fp所指向的文件中。 返回本节目录
9.3.2 字符串读写函数 1.读字符串函数fgets() 《 C语言程序设计》 (Visual C++ 6.0环境) 9.3.2 字符串读写函数 1.读字符串函数fgets() 《 C语言程序设计》 (Visual C++ 6.0环境) 函数fgetc每次只能从文件中读取一个字符,而函数fgets则用来读取一个字符串。该函数的一般格式为: fgets (字符数组, n,文件指针变量) fgets函数的作用是从文件指针变量所指向的文件中读取n-1个字符。如果在读n-1个字符前遇到换行符或EOF标记,则读取结束。读出的字符放到字符数组中,然后在末尾加一个字符串结束标志“\0”。如果该函数调用成功,返回字符数组的首地址,失败时返回NULL。 返回本节目录
9.3.2 字符串读写函数 《 C语言程序设计》 (Visual C++ 6.0环境) 9.3.2 字符串读写函数 【例9.4】使用fgets函数读出文件file.txt中的文字。 程序文件名为l9_4.cpp。 #include “stdio.h“ #include ”stdlib.h“ main() { char ch[50]; /*定义一个字符数组*/ FILE *fp; /*定义一个文件类型的指针变量fp*/ fp=fopen(”file.txt”,“r”); /*打开文本文件file*/ if(fp==NULL) /*打开文件失败则退出*/ { printf(“cannot open this file\n”); exit(0); } fgets(ch,50,fp); /*读出文件中的字符串*/ printf("%s",ch); fclose(fp); } 《 C语言程序设计》 (Visual C++ 6.0环境) 返回本节目录
9.3.2 字符串读写函数 2.写字符串函数fputs() fputs函数,该函数的一般格式为: 9.3.2 字符串读写函数 2.写字符串函数fputs() 《 C语言程序设计》 (Visual C++ 6.0环境) fputs函数,该函数的一般格式为: fputs(字符串,文件指针变量); fputs函数的作用是将字符串写入文件指针所指向的文件中。其中字符串可以是字符常量,也可以是字符数组或指针变量。该函数调用成功时返回0,失败时返回EOF。 如:fputs(“student”,fp); 执行结果是将字符串“student”写入到fp所指向的文件中。 返回本节目录
9.3.3 数据块读写函数 1.读数据块函数fread() 《 C语言程序设计》 (Visual C++ 6.0环境) 9.3.3 数据块读写函数 1.读数据块函数fread() 《 C语言程序设计》 (Visual C++ 6.0环境) fread函数用来从指定文件读一个数据块,例如读一个实数或一个结构体变量的值,该函数的一般格式为: fread(buffer, size, count, 文件指针变量) buffer是读入数据在内存中的存放地址。 size是要读的数据块的字节数。 count是要读多少个size字节的数据项。 fread函数的作用是从文件指针变量指向的文件中读count个长度为size的数据项到buffer所指的地址中。该函数如果调用成功返回实际读入数据块的个数,如果读入数据块的个数小于要求的字节数,说明读到了文件尾或出错。 如9.1.1实例3中通过fread函数读出结构体stu中的一个元素。 返回本节目录
9.3.3 数据块读写函数 2.写数据块函数fwrite() 3.程序实例 《 C语言程序设计》 (Visual C++ 6.0环境) 9.3.3 数据块读写函数 2.写数据块函数fwrite() 《 C语言程序设计》 (Visual C++ 6.0环境) fwrite函数用来将一个数据块写入文件,该函数的一般格式为: fwrite(buffer, size, count, 文件指针变量) fwrite函数的作用是从buffer所指的内存区写count个长度为size的数据项到文件指针变量指向的文件中。该函数如果调用成功返回实际写入文件中数据块的个数,如果写入数据块的个数小于指定的字节数,说明函数调用失败。 3.程序实例 【例9.5】从键盘输入三个学生的姓名,性别,年龄基本信息,存入文 件student.stu中,然后再从文件中读出所输入的数据。 程序文件名为l9_5.cpp。 返回本节目录
9.3.3 数据块读写函数 《 C语言程序设计》 (Visual C++ 6.0环境) 9.3.3 数据块读写函数 #include “stdio.h“ #include <stdlib.h> struct student /*定义结构体*/ { char sname[8]; /*姓名*/ char ssex[2]; /*性别*/ int sage; /*年龄*/ }stu1[3],stu2[3]; void main() { int i; FILE *fp; /*定义文件指针变量*/ fp=fopen(“student.stu”,“wb”); /*只写方式打开文件*/ if(fp==NULL) /*打开失败后退出*/ { printf(“写文件打开失败!”); exit(0); } 《 C语言程序设计》 (Visual C++ 6.0环境) 返回本节目录
9.3.3 数据块读写函数 《 C语言程序设计》 (Visual C++ 6.0环境) 9.3.3 数据块读写函数 fread(&stu2,sizeof(student),3,fp); /*读数据到数组变量*/ printf(“您刚才输入的数据为:\n”); for(i=0;i<3;i++) { printf(“%s %s %d\n”,stu2[i].sname,stu2[i].ssex,stu2[i].sage); } fclose(fp); /*关闭文件*/ } 《 C语言程序设计》 (Visual C++ 6.0环境) 返回本节目录
9.3.3 数据块读写函数 4.C程序实例分析 《 C语言程序设计》 (Visual C++ 6.0环境) 9.3.3 数据块读写函数 4.C程序实例分析 《 C语言程序设计》 (Visual C++ 6.0环境) 程序首先定义用来表示学生信息的结构体,然后以只写方式打开文件student.stu,接下来等待用户从键盘输入三条信息,每输入完一条信息,则往文件中写入一条。程序中使用sizeof运算符计算出一条信息的字节数。程序后半部分以只读方式打开文件,然后一次读出三条信息。(如下图) 返回本节目录
9.3.4 格式化读写函数 1.格式化读文件函数fscanf() 《 C语言程序设计》 (Visual C++ 6.0环境) 9.3.4 格式化读写函数 1.格式化读文件函数fscanf() 《 C语言程序设计》 (Visual C++ 6.0环境) fscanf函数类似于scanf函数,两者都是格式化输入函数,不同的是scanf函数的作用对象是终端键盘,而fscanf函数的作用对象是文件。fscanf函数的一般格式为: fscanf(文件指针变量,“格式控制”,输入列表) “格式控制”与“输入列表”同scanf函数中描述。 fscanf函数的作用是从文件指针变量指向的文件中按指定的格式读取数据到输入列表中的变量中。 如:fscanf(fp, “%d,%d”,&x,&y); 执行结果是从fp指向的文件中读取两个整数到变量x和y中。 返回本节目录
9.3.4 格式化读写函数 2.格式化写文件函数fprintf() 《 C语言程序设计》 (Visual C++ 6.0环境) 9.3.4 格式化读写函数 2.格式化写文件函数fprintf() 《 C语言程序设计》 (Visual C++ 6.0环境) fprintf函数类似于printf函数,两者都是格式化输出函数,只不过两者的作用对象一个文件,一个是终端。fprintf函数的一般格式为: fprintf(文件指针,“格式控制”,输出列表) “格式控制”与“输出列表”同printf函数中描述。 fprintf函数的作用是将输出项按指定的格式写入到文件指针变量所指向的文件中。 如:fprintf(fp, “%d%d”,100,200); 执行结果是将100和200两个整数存放到fp指向的文件中。 注:用fprintf和fscanf函数对文件读写使用方便,容易理解,但由于在输入时要将ASCII码转换为二进制形式,在输出时又要将二进制形式转换成字符,花费时间较多,占用系统资源较大。因此在数据量较大的情况下,最好不用fprintf和fscanf函数,而用fread和fwrite函数。 返回本节目录
9.3.5 整数读写函数 1.读整数函数getw() 《 C语言程序设计》 (Visual C++ 6.0环境) 9.3.5 整数读写函数 1.读整数函数getw() 《 C语言程序设计》 (Visual C++ 6.0环境) getw函数同getc函数的用法类似,只不过getc函数用来读取一个字符,getw函数用来读取一个整数。getw函数的一般格式为: getw(文件指针变量) fprintf函数的作用是从文件指针变量所指向的文件中读取一个整数。如果函数调用成功,返回读取的整数,出错或文件结束时返回EOF。 如:x=getw(fp); 执行结果是从fp指向的文件中读取一个整数赋值给变量x。 返回本节目录
9.3.5 整数读写函数 2.写整数函数putw() 《 C语言程序设计》 (Visual C++ 6.0环境) 9.3.5 整数读写函数 2.写整数函数putw() 《 C语言程序设计》 (Visual C++ 6.0环境) putw函数类似于putc函数。只不过前者写入文件的是整数,后者写入文件的是一个字符,putw函数的一般格式为: putw(整数,文件指针变量) putw函数的作用是写一个整数到文件指针变量所指向的文件中。其中整数可以是整 数常量,也可以是整数变量。如果函数调用成功,返回写入的整数,失败时返回EOF。 如:putw(10,fp); 执行结果是将整数10写入fp指向的文件中。 返回本节目录
9.3.5 整数读写函数 3.C程序实例 《 C语言程序设计》 (Visual C++ 6.0环境) 9.3.5 整数读写函数 3.C程序实例 《 C语言程序设计》 (Visual C++ 6.0环境) 【例9.6】从键盘输入一个任意整数,存放到文件file.txt中,然后再从该文件中读出刚才输入的整数 。 程序文件名为l9_6.cpp。 #include “stdio.h“ #include <stdlib.h> main() { int x,num; FILE *fp; /*定义文件指针变量*/ fp=fopen(”file.txt”,“wb”); /*以只写方式打开文件*/ printf(“请输入一个整数:”); scanf(“%d”,&num); putw(num,fp); /*写入整数到文件中*/ fclose(fp); /*关闭文件*/ fp=fopen(“file.txt”,“rb”); /*以只读方式打开文件*/ x=getw(fp); /*从文件中读出一个整数*/ printf(“\n刚才写入文件的数据是:%d\n”,x); fclose(fp); /*关闭文件*/ } 返回本节目录
9.4 文件的定位 9.4.1 文件的定位 9.4.2 文件位置指针的检测 《 C语言程序设计》 (Visual C++ 6.0环境) 9.4 文件的定位 《 C语言程序设计》 (Visual C++ 6.0环境) 9.4.1 文件的定位 9.4.2 文件位置指针的检测 返回本章目录
9.4.1 文件的定位 1.文件头定位函数rewind() 《 C语言程序设计》 (Visual C++ 6.0环境) 9.4.1 文件的定位 文件中有一个位置指针,指向当前文件读写的位置。C语言的文件既可以顺序存取,又可以随机存取。如果顺序读写一个文件,每次读写完一个数据后,该位置指针会自动移动到下一个数据的位置。如果想随机读写一个文件,那么就必须根据需要改变文件的位置指针,这就会用到文件定位函数。 《 C语言程序设计》 (Visual C++ 6.0环境) 1.文件头定位函数rewind() 函数rewind的一般格式为: rewind(文件指针变量) rewind函数的作用是将文件位置指针返回到文件指针变量指向的文件的开头。该函数无返回值。 返回本节目录
9.4.1 文件的定位 《 C语言程序设计》 (Visual C++ 6.0环境) 9.4.1 文件的定位 【例9.7】将【例9.6】 改为只打开一次文件,写入数据后调用文件头定位函数使文件的位置指针指向文件头,最后读出写入文件的数据。 程序文件名为l9_7.cpp。 #include “stdio.h“ #include <stdlib.h> main() { int x,num; FILE *fp; /*定义文件指针变量*/ fp=fopen(”file.txt”,“wb+”); /*以读写方式打开文件*/ printf(“请输入一个整数:”); scanf(“%d”,&num); putw(num,fp); /*写文件操作*/ rewind(fp); /*文件位置指针返回文件头*/ x=getw(fp); /*读文件操作*/ printf("\n刚才写入文件的数是:%d\n",x); fclose(fp); } 《 C语言程序设计》 (Visual C++ 6.0环境) 返回本节目录
9.4.1 文件的定位 2.随机定位函数fseek() 《 C语言程序设计》 (Visual C++ 6.0环境) 9.4.1 文件的定位 2.随机定位函数fseek() 《 C语言程序设计》 (Visual C++ 6.0环境) 如果能将文件位置指针按需要移动到任意位置,就可以实现对文件的随机读写。函数fseek可以实现这个功能,它的使用格式为: fseek(文件指针变量,位移量,起始位置) “位移量”是指以起始位置为基准点,文件位置指针移动的字节数,它要求必须为长整型数,当用常量表示位移量时要求加后缀“L”。 “起始位置”是位移量的基准点,它的取值可以是0、1或2。含义如下: 该函数如果调用成功返回0,否则返回非零值。 返回本节目录
9.4.1 文件的定位 《 C语言程序设计》 (Visual C++ 6.0环境) 如:fseek(fp,20L,0) 9.4.1 文件的定位 如:fseek(fp,20L,0) 执行结果是将文件位置指针移到距文件头20个字节处。 如:fseek(fp,50L,1) 执行结果是将文件位置指针移到距文件当前位置50个字节处。 如:fseek(fp,-80L,2) 执行结果是将文件位置指针从文件尾向前移动80个字节。 fseek一般用于二进制文件,因为文本文件要发生字符转换,在计算位置时往往会发生混乱。 《 C语言程序设计》 (Visual C++ 6.0环境) 返回本节目录
9.4.1 文件的定位 3.C程序实例 《 C语言程序设计》 (Visual C++ 6.0环境) 9.4.1 文件的定位 3.C程序实例 《 C语言程序设计》 (Visual C++ 6.0环境) 【例9.8】读出【例9.5】中输入的三条信息的第二条 程序文件名为l9_8.cpp。 #include “stdio.h“ #include <stdlib.h> struct student /*结构体定义*/ { char sname[8]; char ssex[2]; int sage; }stu; void main() { FILE *fp; /*定义文件指针变量*/ fp=fopen("student.stu","rb"); if(fp==NULL) { printf("cannot open the file student.stu!"); exit(0); } 返回本节目录
9.4.1 文件的定位 4.C程序实例分析 《 C语言程序设计》 (Visual C++ 6.0环境) 9.4.1 文件的定位 fseek(fp,sizeof(student),0); /*文件位置指针定位*/ fread(&stu,sizeof(student),1,fp);/*读文件*/ printf(“%s %s %d\n”,stu.sname,stu.ssex,stu.sage); fclose(fp); /*关闭文件*/ } 《 C语言程序设计》 (Visual C++ 6.0环境) 4.C程序实例分析 该程序首先以只读方式打开文件,然后调用fseek函数使文件的位置指针从文件头向后移动到第二条信息的位置。最后调用freed函数读出信息。请看下面的动画演示: 打开文件时位置指针 姓名 性别 年龄 调用fseek后的位置指针 返回本节目录
9.4.2 文件位置指针的检测 1.求当前读写位置函数ftell() 《 C语言程序设计》 (Visual C++ 6.0环境) 9.4.2 文件位置指针的检测 1.求当前读写位置函数ftell() 《 C语言程序设计》 (Visual C++ 6.0环境) 读写文件时,文件位置指针的值经常发生变化,不容易知道其当前位置。但在程序设计过程中,明确文件当前的读写位置是很重要的,这就会用到ftell函数,该函数的一般格式为: ftell(文件指针变量) ftell函数的作用是得到文件指针变量所指向的文件的当前读写位置,该函数调用成功返回文件的当前读写位置,该数值为长整型,是指文件位置指针从文件头算起的字节数。该函数调用失败返回-1L。 返回本节目录
9.4.2 文件位置指针的检测 2.检测文件是否结束函数feof() 3.程序实例 9.4.2 文件位置指针的检测 2.检测文件是否结束函数feof() 《 C语言程序设计》 (Visual C++ 6.0环境) 函数feof()用来检测文件内部的位置指针是否位于文件末尾。该函数的调用方法如下: feof(文件指针变量); feof函数的作用是检测文件指针变量指向的文件是否结束,如果结束返回一个非零值,否则返回0。 3.程序实例 在【例9.8】中加入文件位置指针检测函数后,观察程序的输出结果。 返回本节目录
9.4.2 文件位置指针的检测 《 C语言程序设计》 (Visual C++ 6.0环境) 9.4.2 文件位置指针的检测 #include “stdio.h“ #include <stdlib.h> struct student /*结构体定义*/ { char sname[8]; char ssex[2]; int sage; }stu; void main() { FILE *fp; /*定义文件指针变量*/ fp=fopen(“student.stu”,“rb”); /*打开文件*/ printf(“%ld\n”,ftell(fp)); fseek(fp,sizeof(student),0); /*文件位置指针定位*/ printf(“%ld\n”,ftell(fp)); printf("%d\n",feof(fp)); fclose(fp); /*关闭文件*/ } 《 C语言程序设计》 (Visual C++ 6.0环境) 返回本节目录
9.4.2 文件位置指针的检测 4.程序实例分析: 《 C语言程序设计》 (Visual C++ 6.0环境) 该程序的输出结果如下图: 9.4.2 文件位置指针的检测 4.程序实例分析: 《 C语言程序设计》 (Visual C++ 6.0环境) 该程序的输出结果如下图: 这是由于刚打开文件时文件的位置指针位于文件头,所以输出结果为0,当调用fseek函数后,文件位置指针向后移动了所定义的结构体所占的字节数,所以输出结果为16,这时文件的位置指针并没有位于文件尾,也就是说文件没有结束,所以输出feof函数的输出值为0。 返回本节目录
9.5 文件出错的检测 9.5.1 文件出错检测函数ferror() 9.5.2 出错标志置零函数clearerr() 9.5 文件出错的检测 《 C语言程序设计》 (Visual C++ 6.0环境) 9.5.1 文件出错检测函数ferror() 9.5.2 出错标志置零函数clearerr() 返回本章目录
9.5.1 文件出错检测函数ferror() 《 C语言程序设计》 (Visual C++ 6.0环境) 该函数的一般格式为: ferror(文件指针变量) ferror函数的作用是检测文件指针变量指向的文件里的错误。函数的返回值为0时表示没有错误,返回非零值时表示有错误产生。 注意,对同一个文件每调用一次文件读写函数,都会产生一个新的ferror函数值,所以,在调用一个文件读写函数后,应当立即使用ferror函数进行检测,否则信息可能会丢失。 例如我们可以将各例题打开文件的程序代码改为如下: FILE *fp; fp=fopen(“文件名”, “打开方式”); if(ferror(fp)) printf(“打开文件时发生错误!”); 《 C语言程序设计》 (Visual C++ 6.0环境) 返回本节目录
9.5.2 出错标志置零函数clearerr() 《 C语言程序设计》 (Visual C++ 6.0环境) 该函数的一般格式为: clearerr(文件指针变量) clearerr函数的作用是将文件指针变量指向的文件的错误标志和结束标志设置为0。 在文件打开时,出错标志置为0,一旦文件读写过程中出现错误,错误标志被置为非零值,直到同一文件调用clearerr函数或rewind函数。 《 C语言程序设计》 (Visual C++ 6.0环境) 【例9.9】以只写方式打开文件,观察出错标志的变化。 程序名为l9_9.cpp。 #include “stdio.h“ void main() { char c; FILE *fp; fp=fopen(”file.txt”,“w”); /*以只写方式打开文件*/ printf("打开文件时的错误标志为:"); 返回本节目录
9.5.2 出错标志置零函数clearerr() 《 C语言程序设计》 (Visual C++ 6.0环境) printf(“%d\n”,ferror(fp)); /*输出打开文件后的错误标记*/ c=fgetc(fp); /*读文件操作*/ printf(“\n读文件后的错误标志为:”); printf(“%d\n”,ferror(fp)); /*输出读文件后的错误标记*/ clearerr(fp); /*错误标志置0*/ printf(“\n调用错误标志置0函数后的错误标志为:”); printf(“%d\n”,ferror(fp)); /*输出错误标志置0后的错误标记*/ fclose(fp); } 《 C语言程序设计》 (Visual C++ 6.0环境) 该程序的输出结果是: 打开文件时的错误标志为:0 读文件后的错误标志为:32 调用错误标志置0函数后的错误标志为:0 程序在打开文件时,错误标志置0,然后再读文件,由于该文件是以只写方式打开文件,所以读文件时会产生错误,错误标志置为非零值,接着调用错误标志置0函数,又使错误标志从新置为0。 返回本节目录
9.6 综合实训 《 C语言程序设计》 (Visual C++ 6.0环境) 9.6 综合实训 有如图课程表,记录的是星期一至星期五每天的课程。编一程序,该程序应具有以下功能: 《 C语言程序设计》 (Visual C++ 6.0环境) 1.课程表设置,将一星期的课程数据写入到文件中。 2.查阅某天课程,随机读出文件中的相关数据。 3.查阅整个课程表,读出全部数据。 4.退出系统,提示用户系统已经退出。 返回本章目录
9.6 综合实训 《 C语言程序设计》 (Visual C++ 6.0环境) 9.6 综合实训 【例9.10】程序名为l9_10.cpp。 #include <stdio.h> #include <stdlib.h> struct clsset /*定义结构体*/ { char class12[6]; /*1-2节课*/ char class34[6]; /*3-4节课*/ char class56[6]; /*5-6节课*/ }cls[5],cls2; void save() /*定义函数,将课程数据写入文件*/ { FILE *fp; int i; fp=fopen("class","wb"); if(fp==NULL) { printf("cannot open the file."); exit(0); } 《 C语言程序设计》 (Visual C++ 6.0环境) 返回本章目录
9.6 综合实训 《 C语言程序设计》 (Visual C++ 6.0环境) printf("请输入所编排的课程表:\n"); 9.6 综合实训 printf("请输入所编排的课程表:\n"); for(i=0;i<5;i++) { scanf("%s%s%s",&cls[i].class12,&cls[i].class34,&cls[i].class56); fwrite(&cls[i],sizeof(struct clsset),1,fp); } fclose(fp); void somedaycls() /*定义函数,随机读取某天的课程数据*/ { FILE *fp; int no; fp=fopen("class","rb"); if(fp==NULL) { printf("cannot open the file."); exit(0); 《 C语言程序设计》 (Visual C++ 6.0环境) 返回本章目录
9.6 综合实训 《 C语言程序设计》 (Visual C++ 6.0环境) 9.6 综合实训 《 C语言程序设计》 (Visual C++ 6.0环境) printf("请输入星期代号(用1,2,3,4,5表示):"); scanf("%d",&no); if(no>=1 && no<=5) { fseek(fp,(no-1)*sizeof(clsset),0); fread(&cls2,sizeof(clsset),1,fp); printf("\n%s,%s,%s\n",cls2.class12,cls2.class34,cls2.class56); fclose(fp); } else printf("请输入1--5之间的数!\n"); 返回本章目录
9.6 综合实训 《 C语言程序设计》 (Visual C++ 6.0环境) void clssheet() /*读取文件中的全部数据*/ 9.6 综合实训 void clssheet() /*读取文件中的全部数据*/ { FILE *fp; int i; fp=fopen("class","rb"); if(fp==NULL) { printf("cannot open the file."); exit(0); } for(i=0;i<5;i++) { fread(&cls[i],sizeof(clsset),1,fp); printf("%s %s %s\n",cls[i].class12,cls[i].class34,cls[i].class56); fclose(fp); 《 C语言程序设计》 (Visual C++ 6.0环境) 返回本章目录
9.6 综合实训 《 C语言程序设计》 (Visual C++ 6.0环境) void main() { int op; 9.6 综合实训 void main() { int op; printf("1.课程表设置\n"); printf("2.查阅某天课程\n"); printf("3.查阅整个课程表\n"); printf("4.退出系统\n"); printf("请选择要操作的命令(1--4):"); scanf("%d",&op); switch(op) { case 1:save();break; case 2:somedaycls();break; case 3:clssheet();break; case 4:printf("系统已经退出!");break; default:printf("输入错误!"); } 《 C语言程序设计》 (Visual C++ 6.0环境) 返回本章目录