当文件按指定的工作方式打开以后,就可以执行对文件的读和写。下面按文件的性质分类进行操作。针对文本文件和二进制文件的不同性质,对文本文件来说,可按字符读写或按字符串读写;对二进制文件来说,可进行成块的读写或格式化的读写。 [例8-2] 将存放于磁盘的指定文本文件按读写字符方式逐个地从文件读出,然后再将其显示到屏幕上。采用带参数的main( ),指定的磁盘文件名由命令行方式通过键盘给定。 [例8-3] 从键盘输入字符,存到磁盘文件test.txt中: 2. 读写字符串 [例8-4] 向磁盘写入字符串,并写入文本文件test.txt: 运行结束后,我们利用dos的type命令列表文件: [例8-5] 从一个文本文件test1.txt中读出字符串,再写入令一个文件test2.txt。 3. 格式化的读写 [例8-6] 将一些格式化的数据写入文本文件,再从该文件中以格式化方法读出显示到屏
幕上,其格式化数据是两个学生记录,包括姓名、学号、两科成绩。 #i nclude<stdio.h> main( ) { FILE *fp; int i; struct stu{ /*定义结构体类型*/ char name[15]; char num[6]; float score[2]; }student; /*说明结构体变量*/ if((fp=fopen("test1.txt","w"))==NULL) { /*以文本只写方式打开文件*/ printf("cannot open file"); exit(0); } printf("input data:\n"); for( i=0;i<2;i++) { scanf("%s %s %f %f",student.name,student.num,&student.score[0], &student.score[1]); /*从键盘输入*/ fprintf(fp,"%s %s %7.2f %7.2f\n",student.name,student.num, st udent.score[0],student.score[1]); /* 写入文件*/ } fclose(fp); /*关闭文件*/ if((fp=fopen("test.txt","r"))==NULL) { /*以文本只读方式重新打开文件*/ printf("cannot open file"); exit(0); } printf("output from file:\n"); while (fscanf(fp,"%s %s %f %f\n",student.name,student.num,&student.score[0],student.score[1])!=EOF) / *从文件读入* / printf("%s %s %7.2f %7.2f\n",student.name,student.num, student.score[0],student.score[1]); /* 显示到屏幕*/ fclose(fp); /*关闭文件*/ } 程序设计一个文件变量指针,两次以不同方式打开同一文件,写入和读出格式化数据,有一点很重要,那就是用什么格式写入文件,就一定用什么格式从文件读,否则,读出的数据与格式控制符不一致,就造成数据出错。上述程序运行如下: input data: xiaowan j001 87.5 98.4 xiaoli j002 99.5 89.6 output from file: xiaowan j001 87.50 98.40 xiaoli j002 99.50 89.60 列表文件的内容显示为:
c:\>type test.txt xiaowan j001 87.50 98.40 xiaoli j002 99.50 89.60 此程序所访问的文件也可以定为二进制文件,若打开文件的方式为: if ((fp=fopen("test1.txt","wb"))==NULL) { / * 以二进制只写方式打开文件* / printf("cannot open file"); exit(0); } 其效果完全相同。 4. 成块读写
前面介绍的几种读写文件的方法,对其复杂的数据类型无法以整体形式向文件写入或从文件读出。C语言提供成块的读写方式来操作文件,使其数组或结构体等类型可以进行一次性读写。成块读写文件函数的调用形式为: int fread(void *buf,int size,int count,FILE *stream) int fwrite(void *buf,int size,int count,FILE *stream) fread()函数从stream 指向的流文件读取count (字段数)个字段,每个字段为size(字段长度)个字符长,并把它们放到b u f(缓冲区)指向的字符数组中。 fread()函数返回实际已读取的字段数。若函数调用时要求读取的字段数超过文件存放的字段数,则出错或已到文件尾,实际在操作时应注意检测。 fwrite( )函数从buf(缓冲区)指向的字符数组中,把count(字段数)个字段写到stream所指向的流中,每个字段为size个字符长,函数操作成功时返回所写字段数。 关于成块的文件读写,在创建文件时只能以二进制文件格式创建。 [例8-7] 向磁盘写入格式化数据,再从该文件读出显示到屏幕。
#i nclude "stdio.h" #i nclude "stdlib.h" main( ) { FILE *fp1; int i; struct stu{ / *定义结构体*/ char name[15]; char num[6]; float score[2]; }student; if((fp1=fopen("test.txt","wb"))==NULL) { /*以二进制只写方式打开文件* / printf("cannot open file"); exit(0); } printf("input data:\n"); for( i=0;i<2;i++) { scanf("%s %s %f %f",student.name,student.num,&student.score[0],&student.score[1]); /* 输入一记录*/ fwrite(&student,sizeof(student),1,fp1); /* 成块写入文件*/ } fclose(fp1); if((fp1=fopen("test.txt","rb"))==NULL) { /*重新以二进制只写打开文件*/ printf("cannot open file"); exit(0); } printf("output from file:\n"); for (i=0;i<2;i++) { fread(&student,sizeof(student),1,fp1); /* 从文件成块读*/ printf("%s %s %7.2f %7.2f\n",student.name,student.num,student.score[0],student.score[1]); /* 显示到屏幕*/ } fclose(fp1); } 运行程序: input data: xiaowan j001 87.5 98.4 xiaoli j002 99.5 89.6 output from file: xiaowan j001 87.50 98.40 xiaoli j002 99.50 89.60 通常,对于输入数据的格式较为复杂的话,我们可采取将各种格式的数据当做字符串输入,然后将字符串转换为所需的格式。C提供函数: int atoi(char *ptr) float atof(char *ptr) long int atol(char *ptr) 它们分别将字符串转换为整型、实型和长整型。使用时请将其包含的头文件math.h或stdlib.h写在程序的前面。 |
|