440 likes | 584 Views
文件. 第 六 章 文件. 本 章 要 点. 文件的基本概念 文件的基本函数 文件的顺序读写 文件的随机读写 文件简单应用. § 6 -1 文件概述. 文件的定义 文件:存储在外部介质上(如磁盘等外存储器) 的 数据 或 信息 的集合。 例如:程序文件中保存着程序,而数据文件中保存着数据。 C7 .C : C 语言的源程序 文本文件 C 7 .OBJ : 目标文件 二进制文件 C 7 .EXE : 可执行文件 二进制文件 文件的性质
E N D
第六章 文件 本 章 要 点 • 文件的基本概念 • 文件的基本函数 • 文件的顺序读写 • 文件的随机读写 • 文件简单应用
§6-1 文件概述 • 文件的定义 文件:存储在外部介质上(如磁盘等外存储器)的数据或信息的集合。 例如:程序文件中保存着程序,而数据文件中保存着数据。 C7.C: C语言的源程序 文本文件 C7.OBJ: 目标文件 二进制文件 C7.EXE: 可执行文件 二进制文件 • 文件的性质 文件是一个有序的数据序列。文件的所有数据之间有着严格的排列次序的关系(类似数组类型的数据),要访问文件中的数据,必须按照它们的排列顺序,依次进行访问。
程序 数据区 §6-1 文件概述 • 系统对文件的处理过程 系统对文件的处理过程就是对文件进行输入/输出操作的过程。 文件输入/输出的一般过程: 写文件称为输出 输出文件缓冲区 文件 输入文件缓冲区 计算机外存 计算机内存 读文件称为输入
§6-1 文件概述 文件的分类 ◆ 从文件数据的组织形式看 数据的组织形式是指数据在磁盘上是以什么格式进行存储的。 从这个角度看,文件分为两类: 。ASCII文件(或称文本文件,即TEXT文件) 。二进制文件 文本文件中保存的数据,采用ASCII码作为存储方式,先将全部数据转换为ASCII码形式。每个ASCII字符占用一个字节。 ASCII文件在DOS操作系统下可以直接阅读。 二进制文件中保存的数据,是将数据在内存中二进制存储格式不做任何转换,直接存入文件中。 二进制文件在操作系统下不能直接阅读。
’1’ ’0’ ’2’ ’4’ 0000 0100 0000 0000 0000 0100 0000 0000 §6-1 文件概述 • 两种文件组织形式 • ◆ 例如:将整数1024存储在不同组织形式的文件中 ASCII文件:ASCII码 占用4个字节 内存中的存储形式:补码 二进制文件:补码 占用2个字节 • 两个不同格式文件的比较 • 在ASCII文件中,每个字符是以ASCII码形式存储,方便了对字符的逐个处理,同时在操作系统下,可以直接识别。 • 缺点是占用磁盘存储空间多,并且系统要付出由二进制形式向ASCII转换的时间开销。 • 用二进制形式输出,可以节省磁盘空间和转换时间,但输出的数据因为是内存的格式,在操作系统下不能直接识别。
§6-1 文件概述 • 文件的分类 ◆ 从用户观点看 从用户使用的观点看,文件可分为两类: 。普通文件(亦称为磁盘文件) 。特殊文件(亦称为标准设备文件或标准I/O文件) 普通文件是以磁盘为对象且无其它特殊性能的文件。 特殊文件是以终端为对象的标准的设备文件。 在C语言中,“文件”的概念具有更广泛的意义,它把与每台主机相连的所有输入输出设备都看作是一个文件。即把实际的物理设备抽象为逻辑文件,它们也被称为设备文件。 例如:键盘是输入文件stdin (标准输入文件) 显示器是输出文件stdout(标准输出文件) 打印机是输出文件PRN
§6-2 文件处理 • 文件指针 在缓冲文件系统中,对每个正在使用的文件都要说明并使用一个FILE类型的结构变量,该结构变量用于存放文件的有关信息,如文件名、文件状态等。 在C语言中,无论是一般磁盘文件还是设备文件,都要通过文件结构的数据集合进行输入输出处理。 文件结构不需要用户自己定义,是由系统事先已经定义好的,固定包含在头文件 stdio.h 中。 typedef struct { int _fd; /* 文件位置指针,即当前文件的读写位置 */ • int _cleft; /* 文件缓冲区中剩余的字节数 */ • int _mode; /* 文件操作模式 */ • char * nextc; /* 用于文件读写的下一个字符位置 */ • char * _buff; /* 文件缓冲区位置(指针) */ • } FILE ; FILE是文件结构类型的类型名。
§6-2 文件处理-文件指针 • 文件指针 文件结构在打开文件时由操作系统自动建立,用户使用文件时无需重复定义。文件结构中最重要的信息是:记录了文件读写操作时的位置指针。 在C程序中,凡是要对已打开的文件进行操作,都要通过指向该文件结构的指针。为此,需要在程序中说明指向文件结构的指针,即定义FILE型(文件型)的指针变量。 • 文件型指针变量说明形式 FILE * 文件型指针变量名; 例如: FILE * fp; /* fp 是一指针变量,指向文件结构 */ 当要同时使用多个文件时,则必须有多个不同的文件指针。
§6-2 文件处理-标准设备文件 • 系统标准设备文件 标准设备文件是由系统控制,由系统自动打开和关闭,标准设备文件的文件结构的指针由系统命名,用户在程序中可直接使用。 • C语言中提供了三个标准设备文件的指针: stdin 标准输入文件(键盘) stdout 标准输出文件(显示器) stderr 标准错误输出文件(显示器)
§6-2 文件处理-操作文件的一般步骤 • 使用文件的一般步骤 打开文件————操作文件————关闭文件 打开文件:建立用户程序与文件的联系,为文件开辟文件缓冲区。 操作文件:是指对文件的读、写、追加和定位操作。 读操作:是从文件中读出数据,即将文件中的数据读入计算机; 写操作:是向文件中写入数据,即向文件输出数据。 追加操作:将数据写到原有数据的后面。 定位操作:文件读写位置指针。 关闭文件:切断文件与程序的联系,将文件缓冲区的内容写入磁盘,并释放文件缓冲区。 C语言通过标准I/O库(stdio.h)函数实现文件操作
§6-2 文件处理-fopen • 打开文件(fopen) • fopen函数的调用形式是: • FILE * fp; • fp = fopen ( 文件名, 文件使用方式); • 文件名:需要打开的文件名称(字符串)。 • 文件使用方式:是具有特定含义的符号。 • 函数功能 • 按指定的文件使用方式打开指定的文件。 • 若文件打开成功,则返回值为非NULL指针; • 若文件打开失败,返回NULL。
§6-2 文件处理-fopen的三种方式 • 打开文件(fopen) fopen函数的调用形式是: FILE * fp; fp = fopen ( 文件名, 文件使用方式); • 文本文件的三种基本打开方式 • ”r”:只读方式。为读(输入)文本文件打开文件。若文件不存在,则返回NULL。 • ”w”:只写方式。为写(输出)文本文件打开文件。若文件不存在,则建立一个新文件;若文件已存在,则要将原来的文件清空。 • ”a”:追加方式。在文本文件的末尾增加数据。若文件已存在,则保持原来文件的内容,将新的数据增加到原来数据的后面;若文件不存在,则返回NULL。
§6-2 文件处理-fopen的打开方式 • 二进制文件的三种基本打开方式 ”rb”:只读方式。 ”wb”:只写方式。 ”ab”:追加方式。 • 文件的其他打开方式 ”r+”:可以文本文件进行读/写操作。 若文件不存在返回NULL;若文件存在内容不会被清空。 ”w+”:可以文本文件进行读/写操作。 若文件已经存在,则要先将文件原来的内容清空。 ”a+”:可以文本文件进行读/追加操作。文件内容不会清空。 ”rb+”:可以对二进制文件进行读/写操作。 ”wb+”:可以对二进制文件进行读/写操作。 ”ab+”:可以对二进制文件进行读/追加操作。
§6-2 文件处理-fopen • 文件打开方式小结 • 文件使用方式 含 义 • ━━━━━━━━━━━━━━━━━━━━━━━━━━ • "r" (只读) 为输入打开一个文本文件 • "w" (只写) 为输出打开一个文本文件 • "a" (追加) 向文本文件尾增加数据 • "rb" (只读) 为输入打开一个二进制文件 • "wb" (只写) 为输出打开一个二进制文件 • "ab" (追加) 向二进制文件尾增加数据 • "r+" (读写) 为读/写打开一个文本文件 • "w+" (读写) 为读/写建立一个新的文本文件 • "a+" (读写) 为读/写打开一个文本文件 • "rb+" (读写) 为读/写打开一个二进制文件 • "wb+" (读写) 为读/写建立一个新的二进制文件 • “ab+” (读写) 为读/写打开一个二进制文件
§6-2 文件处理-fopen • 常见文件打开操作 if ( ( fp = fopen ("filename", "r") ) == NULL ) { printf (”Cannot open file.\n”); exit (0); } 含义:以只读方式打开文件名为filename的文件。 由系统打开的三个标准文件,在程序中不需要再次打开,可以直接使用它们的文件指针进行操作。 stdin 标准输入文件(键盘) stdout 标准输出文件(显示器) stderr 标准错误输出文件(显示器)
§6-2 文件处理-fclose • 关闭文件(fclose) fclose函数的调用形式是: FILE * fp; fclose ( fp ); fp:已经打开的文件指针。 • 函数功能 关闭fp指定的文件,切断缓冲区与该文件的联系,并释放文件指针。 若文件关闭成功,则返回值为0; 若文件关闭失败,返回非0值。
§6-3 文件顺序读写 • 文件顺序操作 对文件的操作(文件读写)必须按文件中字符的先后顺序进行,只能在操作了第i个字符之后,才能操作第i+1个字符。 在对文件操作时,文件的位置指针由系统自动向后(文件尾方向)移动。 • 进行顺序操作的函数 字符输入输出函数 fgetc fputc 字符串输入输出函数 fgets fputs 格式化输入输出函数 fscanf fprintf 数据块输入输出函数 fread fwrite
§6-3 文件顺序读写-fgetc/fputc • 字符输入输出( fgetc / fputc ) 输入函数fgetc(): ch = fgetc(fp); fp为已经打开的文件的指针 函数功能:从指定的文件中读取一个字符。即:从fp所指向的文件(该文件必须是以读或读写方式打开的)中读取一个字符返回,读取的字符赋给变量ch。若读取字符时文件已经结束出错: 对于ASCII文件,文件结束时,返回文件结束标记EOF(-1)。 对于二进制文件,要使用feof函数来判断文件是否结束。 输出函数fputc(): fputc(ch,fp); ch为需要输出的字符 函数功能: 将一个字符输出到指定文件中。即将字符变量ch中的字符输出到fp所指向的文件。若输出操作成功,该函数返回输出的字符;否则,返回EOF。
§6-3 文件顺序读写-fgetc/fputc • 例:显示文件的内容 • #include <stdio.h> • main ( ) • { FILE *fp; • char filename[20], ch; • printf ("Enter filename:"); • scanf("%s",filename); /* 输入文件名 */ • if ((fp = fopen (filename,"r"))==NULL) /* 打开文件 */ • { printf("file open error.\n"); /* 出错处理 */ • exit (0); } • while ((ch = fgetc(fp) )!=EOF) /* 从文件中读字符 */ • putchar(ch); • fclose (fp); } /* 关闭文件 */
§6-3 文件顺序读写-fgetc/fputc • 例:使用标准输出文件显示文件的内容 • #include <stdio.h> • main ( ) • { FILE *fp; • char filename[20], ch; • printf ("Enter filename:"); • scanf(“%s”,filename); /* 输入文件名 */ • if ((fp = fopen (filename,“r”))==NULL) /* 打开文件 */ • { printf(“file open error.\n”); /* 出错处理 */ • exit (0); } • while ((ch=fgetc(fp) )!=EOF) /* 从文件中读取字符 */ • fputc(ch,stdout); /* 向标准输出文件中输出(显示) */ • fclose (fp); }/* 关闭文件 */
例:文件复制 • #include <stdio.h> • main ( ) • { FILE *fp1, *fp2; • char file1[20], file2[20], ch; • printf (”Enter filename1:”); scanf("%s",file1); • printf ("Enter filename2:"); scanf("%s",file2); • if(( fp1 = fopen (file1, ”r”)) == NULL) /* 打开文件1 */ • { printf("file1 open error.\n"); • exit (0); } • if((fp2 = fopen (file2, ”w”)) == NULL) /* 打开文件2 */ • { printf("file2 open error.\n"); • exit (0); } • while((ch = fgetc(fp1) )!= EOF) /* 从文件fp1中读字符 */ • fputc (ch,fp2); /* 写入文件fp2中 */ • fclose (fp1); • fclose (fp2); • }
§6-3 文件顺序读写-fgets • 字符串输入输出( fgets / fputs ) 输入函数: fget(s, n, fp) char s[ ]; int n; FILE *fp; 函数功能: 从 fp 所指向的文件中读取长度不超过 n-1 个字符的字符串,并将该字符串放到字符数组 s 中。函数的返回值为字符数组 s 的首地址;如果文件结束或出错,则返回 NULL。 情况1:已读入n-1个字符 ,则:s中存入n-1个字符,串尾为\0 情况2:读入字符遇到\n,则:s中存入实际读入的字符,串尾为\n\0 情况3:读入字符遇到文件尾 ,则:s中存入实际读入的字符,EOF不会存入数组,串尾为\0 情况4:当文件已经结束时,继续读文件 ,则:函数的返回值为 NULL,表示文件结束
abcd\n f abcd\nf s s s f d a b \0 \n c \0 \0 执行过程 初始状态 d 文件指针自动向后移动 b 文件指针自动向后移动 a 文件指针自动向后移动 §6-3 文件顺序读写-fgets • fgets运行实例 打开文本文件:fp ①、fgets ( s, 4, fp); 文件的位置指针 顺序读入3个字符,存入数组,加上\0 ②、fgets ( s, 4, fp); 顺序读入 \n ,存入数组, 退出,加上\0 ③、fgets ( s, 4, fp); 顺序读入遇到 EOF,不存, 退出,加上\0 EOF ④、fgets ( s, 4, fp); 读入 EOF,不存, 函数的返回值为 NULL 读入字符: \n 文件指针自动向后移动 c 文件指针自动向后移动 f 文件指针自动向后移动
§6-3 文件顺序读写-fgets • 例:显示文件内容并加上行号 • #include <stdio.h> • main ( ) • { FILE * fp; • char file[20], str[10]; • int flag=1, i=0; /* flag标志变量,1:开始新行。i为行号 */ • printf ("Enter filename:"); scanf("%s",file); • if ( ( fp = fopen (file, "r")) == NULL ) /* 打开文件 */ • { printf("file1 open error.\n"); exit (0); } • while ( fgets( str,10,fp1)!=NULL) /* 从文件中读出字符串 */ • {if (flag) printf ("%3d:%s", ++i, str); /* 显示行号 */ • else printf ("%s", str); • if ( str [strlen(str)-1] == '\n' ) flag=1; • else flag=0; } • fclose (fp); }
§6-3 文件顺序读写-fputs • 字符串输入输出( fgets / fputs ) • 输出函数: • fputs(s, fp); • char s[ ]; FILE *fp; • 函数功能: • 将s指向的字符串或字符串常量写入文件fp。输出的字符串写入文件时,字符串结束标记“\0”被自动舍去。 • 函数调用成功,则返回值为0;否则,失败返回文件结束标记EOF。
§6-3 文件顺序读写-fputs • 例:复制文本文件。 • #include <stdio.h> • main ( ) • { FILE *fp1, *fp2; • char file1[20], file2[20], s[10]; • printf ("Enter filename1:"); scanf("%s",file1); • printf ("Enter filename2:"); scanf("%s",file2); • if ((fp1 = fopen (file1, "r"))== NULL ) /* 打开文件1 */ • { printf("file1 open error.\n"); exit (0); } • if ((fp2=fopen(file2, "w"))== NULL ) /* 打开文件2 */ • { printf("file2 open error.\n"); exit (0); } • while(fgets( s,10,fp1 ) != NULL ) /* 从fp1中读出字符串 */ • fputs ( s, fp2 ); /* 将字符串写入文件fp2中 */ • fclose (fp1); • fclose (fp2); }
§6-3 文件顺序读写-fscanf/fprintf • 格式化输入输出( fscanf / fprintf ) • 输入函数: • fscanf(fp,格式控制符,变量地址表) FILE *fp; • 函数功能: • 从 fp 所指向的ASCII文件中读取字符,按格式控制符的含义存入对应的变量中,返回值为输入的数据个数。 • fscanf与scanf类似,格式控制符相同。 • 输出函数: • fprintf(fp,格式控制符,表达式列表) FILE *fp; • 函数功能: • 将表达式列表中的数据,按照格式控制符的说明,存入 fp 所指向的ASCII文件中,返回值为实际存入的数据个数。 • fprintf与printf类似,格式控制符相同。
§6-3 文件顺序读写-fread/fwrite • 数据块输入输出( fread / fwrite) • 输入函数: fread(buffer, size, count, fp) • char * buffer; unsigned size; int count; FILE *fp; • 函数功能: • 从二进制文件 fp中读取count个数据块存入buffer中,每个数据块的大小为size个字节。操作成功,函数的返回值为实际读入的数据块的数量;若文件结束或出错,返回值为0。 • 输出函数: fwrite(buffer, size, count, fp) • char * buffer; unsigned size; int count; FILE *fp; • 函数功能: • 将buffer中的count个数据块写入二进制文件 fp中,每个数据块的大小为size个字节。操作成功,函数的返回值为实际写入文件的数据块的数量;若文件结束或出错,返回值为0。
§6-3 文件顺序读写-fread/fwrite • 例:从键盘输入3个学生的数据,将它们存入文件student;然后再从文件中读出数据,显示在屏幕上。 • #define SIZE 3 • struct student /* 定义结构 */ • { long num; • char name[10]; • int age; • char address[10]; • } stu[SIZE], out; • void fsave ( ) • { FILE *fp; • int i; • if ((fp=fopen("student", "wb")) == NULL) /* 二进制写方式 */ • { printf ("Cannot open file.\n"); exit(1); } • for ( i=0; i<SIZE; i++ ) /* 将结构以数据块形式写入文件 */ • if ( fwrite(&stu[i], sizeof(struct student), 1, fp) != 1) • printf("File write error.\n"); /* 写过程中的出错处理 */ • fclose (fp); /* 关闭文件 */ • }
§6-3 文件顺序读写-fread/fwrite • 例:主函数。 • main ( ) { FILE *fp; int i; for ( i=0; i<SIZE; i++ ) /* 从键盘读入学生的信息(结构) */ { printf("Input student %d:", i+1); scanf("%ld%s%d%s",&stu[i].num,stu[i].name,&stu[i].age,stu[i].address); } fsave( ); /* 调用函数保存学生信息 */ fp = fopen ("student", "rb"); /* 以二进制读方式打开数据文件 */ printf (" No. Name Age Address\n"); while( fread(&out, sizeof(out),1,fp) ) /* 以读数据块方式读入信息 */ printf("%8ld %-10s %4d %-10s\n",out.num,out.name,out.age,out.address); • fclose(fp); /* 关闭文件 */ • }
§6-4 文件随机读写 文件读写操作的内部机制 • 文件的读写是通过文件系统内部的“位置指针”进行的。 • 当打开一个文件时,系统自动为打开的文件建立一个位置指针,对该文件的读写操作均通过位置指针进行操作。 • fopen后位置指针指向文件中第1个(将要读写)字节。 • 文件结束时,位置指针指向文件最后1个字节的下1个位置。 顺序读写操作 在顺序读写文件时,文件的位置指针由系统自动控制,每次读写操作后,系统都会将位置指针移到下一个数据的位置。在不改变位置指针的情况下,只能对文件进行顺序操作。 随机读写操作 通过改变文件的位置指针,可在文件的任意位置进行读写操作。
§6-4 文件随机读写-fseek 位置指针移动(fseek) fseek(fp,offset, position) FILE *fp; long offset; int position; 函数功能: 将指定文件 fp的文件位置指针按照position规定的方式移动offset个字节。移动成功返回值为0;否则,返回值为非0。 position为起始点,指出以文件的什么位置为基准进行移动: 0 ── 文件的开头; 1 ── 文件的当前位置; 2 ── 文件的末尾。 fseek(fp,50,0) 从文件头开始向前(文件尾方向)移动50个字节 fseek(fp,-10,1) 从当前位置向后(文件头方向)移动10个字节 fseek(fp,-20,2) 从文件尾开始向后(文件头方向)移动20个字节
§6-4 文件随机读写-rewind/ftell • 位置指针返回到文件头( rewind ) rewind ( fp ) FILE *fp; 函数功能: 使 fp 指定的文件的位置指针重新定位到文件的头位置。 取位置指针( ftell ) ftell ( fp ) FILE *fp; 函数功能: 得到 fp 所指向文件的当前读写位置,即位置指针的当前值。 该值是一个长整型数,是位置指针从文件开始处到当前位置的位移量的字节数。 如果函数的返回值为 -1L,表示出错。
§6-5 文件检测-feof/ferror/clearerr 检测文件操作后的状态 C语言提供了两种手段来反映函数调用的情况和文件的状态。 • 由函数的返回值可以知道文件调用是否成功。 • 由C函数库提供对文件操作状态和操作出错的检测函数。 检测文件结束函数 feof (fp) 功能:若文件已经结束,返回值为非0;若文件尚未结束,返回值为0。 检测文件出错函数 ferror (fp) 功能:若文件出错,返回值为非0;若文件未出错,返回值为0。 清除出错标记及文件结束标记 clearerr (fp) 功能:清除文件 fp 的出错和文件结束标记。
§6-6 文件实例 在C语言中,从计算机的内存中将数据写入文件中,称为。 • A. 输入 B. 输出 C. 修改 D. 删除 • 答案:B C语言可以处理的文件类型是。 • A. 文本文件和数据文件 B. 文本文件和二进制文件 • C. 数据文件和二进制文件 D. 以上答案都不完全 • 答案:B 下列关于文件的结论中正确的是。 • A. 对文件操作必须先关闭文件 • B. 对文件操作必须先打开文件 • C. 对文件的操作顺序没有统一规定 • D. 以上三种答案全是错误的 • 答案:B
§6-6 文件实例 • 系统的标准输入文件是。 • A. 键盘 B. 显示器 C. 软盘 D. 硬盘 • 答案:A • 对文件的基本操作过程是。 • A. 打开——操作——关闭 B. 打开(可省)——操作——关闭 • C. 打开——操作——关闭(可省) D. 以上三个答案都不对 • 答案:A • 为了显示一个文本文件的内容,在打开文件时,文件的打开方式应当是。 • A. "r+" B. "w+” C. "wb+" D. "ab+" • 答案:A
§6-6 文件实例 • 要打开一个已存在的非空文件“file”用于修改,选择正确的语句是。 • A. fp=fopen("file", "r"); B. fp=fopen("file", "a+"); • C. fp=fopen("file", "w"); D. fp=fopen("file", "r+"); • 答案:D • 为了改变文件的位置指针,应当使用的函数是。 • A. fseek( ) B. rewind( ) C. ftell( ) D. feof() • 答案:A • 要将一个结构数组存入一个二进制文件中,应当使用函数。 • A. fputc B. fputs C. fprintf D. fwrite • 答案:D
§6-6 文件实例 • 例:在屏幕上显示文件file1.c的内容,并将文件file1.c复制到文件file2.c。 • #include <stdio.h> • main( ) • { FILE *fp1. *fp2; • fp1 = fopen("file1.c", "r"); • fp2 = fopen("file2.c", "w"); • while ( ! feof(fp1) ) /* 在屏幕上显示file1.c的内容 */ • putchar ( fgetc(fp1) ); /* feof判断文件是否结束 */ • rewind(fp1); /* 完成显示后,fp1的指针已指到文件的末尾, • 为了完成复制,使file1.c的位置指针重返回文件头 */ • while ( ! feof(fp1) ) • fputc ( fgetc(fp1), fp2 ); • /* 把文件file1.c的内容复制到file2.c中 */ • fclose(fp1); fclose(fp2); }
§6-6 文件实例 • 程序的功能是:显示指定文件并加上行号(程序选择填空)。 • main ( ) • { char s[20], filename[20]; FILE * fp; • int flag=1, 【 1 】; • printf("Enter filename:"); gets (filename); • if ( ( fp=fopen(filename, "r") ) 【 2 】 ) • { printf ("File open error !\n"); exit(0); } • while ( fgets( s, 20, fp) 【 3 】 ) • {if (【 4 】) printf ("%3d:%s", ++i, s); • else printf ("%s", s); • if (【 5 】) flag=1; • elseflag=0; • } • fclose (fp); • } • 可供选择答案: • 1. A) i B) i=-1 C) i=0 D) i=1 • 2. A) ==NULL B) != NULL C) == EOF D) != EOF • 3. A) ==NULL B) != NULL C) == EOF D) != EOF • 4. A) flag==0 B) flag==1 C) flag=0 D) flag=1 • 5. A) s[strlen(s)]=='\n' B) s[strlen(s)-1]=='\0' • C) s[strlen(s)-1]=='\0' D) s[strlen(s)-1]=='\n’ • 答案:C A B B D
§6-6 文件实例 • 从键盘接受姓名(例如:输入“ZHANG SAN”),在文件“try.dat”中查找,若文件中已有刚输入的姓名,则显示提示信息;若文件中没有刚输入的姓名,则将该姓名存入文件。要求: • ①若磁盘文件"try.dat",已存在,则要保留文件中原来的信息;若文件"try.dat"不存在,则在磁盘上建立一个新文件。 • ②当输入的姓名为空时(长度为0),结束程序。
main( ) • { FILE *fp; int flag; char name[30], data[30]; • if ( (fp=fopen("try.dat", 【 ① 】))==NULL ) exit(0); • do { printf ("Enter name:"); gets(name); • if (strlen(name)==0)break; • strcat (name, "\n"); • 【 ② 】; • flag=1; • while ( flag && (fgets(data, 30, fp)【 ③ 】) ) • if ( strcmp(data, name) == 0 ) • 【 ④ 】; • if (flag) fputs(name, fp); • else printf ("\tData enter error !\n") ; • } while ( 【 ⑤ 】 ); • fclose(fp); • } • 可供选择的答案: • ① A. "r+" B. "w+" C. "a+" D. "w" • ② A. rewind(fp) B. fseek(fp,0,1) C. ftell(fp) D. 空语句 • ③ A. !=NULL B. ==NULL C. !=EOF D. ==EOF • ④ A. break B. flag=0 C. continue D. flag=-1 • ⑤ A. ferror(fp)!=0 B. ferror(fp)==0 C. flag==0 D. flag==-1 • 答案: ①C ②A ③A ④B ⑤B
读入文件从中检索出6种关键字,并统计、输出每种关键字在文件中出现的次数。规定:单词是以空格或‘\t’、‘\n’结束的字符串(程序填空)。 FILE *cp; char fname[20], buf[100]; int num; struct key { char word[10];int count; • } keyword[ ] = { "if", 0, "char", 0, "int", 0, • "else", 0, "while", 0, "return", 0 }; char * getword ( FILE *fp ) { int i=0; char c; while ( (c=getc(fp)) != EOF && (c==' '||c=='\t'||c=='\n')) ; if ( c==EOF) return(NULL) ; else buf[i++]=c; while ( ( c=___( 1 )___ && c!=' ' && c!='\t' && c!='\n') buf[i++] = c; • buf[i]='\0'; • return (buf); • } 1). A. fgetc(fp))!=EOF B. fgetc(fp))==EOF C. fegtc(fp)) D. fgetc(fp)<>EOF
lookup ( char *p ) { int i; char *q, *s; for (i=0; i<num; i++) { q = _____( 2 )_____; s = p; while ( *s && ( *s==*q ) ) { ______( 3 )_____ } if ( ______( 4 )_____ ) { keyword[i].count++; break; }}} main( ) {int i; char *word; printf ("Input file name:"); scanf("%s", fname); if ( (cp=fopen(fname, "r")) ==NULL ) exit(0); num = sizeof(keyword) / sizeof(sruct key); while (______(5)_____) lookup(word); fclose(fp); for ( i=0; i<num; i++ ) printf ("keyword:%-20s count=%d\n",keyword[ ].word,keyword[i].count); } 2). A. keyword[i].word[0] B. &keyword[i].word C. &keyword[i].word[0] D. keyword[i].word 3). A. s++; q++; B. s++; C. q++ D. s=q; 4). A. s==q; B. *s=*q C. *s=*q D. s!=NULL 5).A. (word==getword(cp))!=NULL B. word=getword(cp)!=NULL C.(word=getword(cp))==NULL D. (word=getword(cp))!=NULL 答案:1). A 2). C 3). A 4). B 5). D