1 / 59

项目 10 学生成绩单的保存与读取

项目 10 学生成绩单的保存与读取. 项目 10 学生成绩单的保存与读取. 【 学习目标 】. (1) 掌握 C 语言中文件的相关概念。 (2) 掌握文件有关操作常用标准库函数的使用。 (3) 掌握对文件的简单输入 / 输出操作。. 任务 10.1 将多个学生成绩单顺序读写到文件中. 任务介绍. 考试结束后,得到了全班学生多门课程的成绩。要求将一小组 3 个学生成绩信息写入到文件存档保存。学生成绩信息是个结构体,包括学生姓名、性别与学生成绩 3 个成员变量。 学生成绩信息如下: 肖飞 男 86 56 76 李雪 女 75 95 83

brick
Download Presentation

项目 10 学生成绩单的保存与读取

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. 项目10 学生成绩单的保存与读取

  2. 项目10 学生成绩单的保存与读取 【学习目标】 • (1) 掌握C语言中文件的相关概念。 • (2) 掌握文件有关操作常用标准库函数的使用。 • (3) 掌握对文件的简单输入/输出操作。

  3. 任务10.1 将多个学生成绩单顺序读写到文件中 任务介绍 考试结束后,得到了全班学生多门课程的成绩。要求将一小组3个学生成绩信息写入到文件存档保存。学生成绩信息是个结构体,包括学生姓名、性别与学生成绩3个成员变量。 学生成绩信息如下: 肖飞男86 56 76 李雪女75 95 83 郭键男91 89 61 要求输出格式为: 学生成绩信息为: 肖飞男86 56 76 李雪女75 95 83 郭键男91 89 61

  4. 任务10.1 将多个学生成绩单顺序读写到文件中 解决思路 方法: S1:初始化学生成绩信息到结构体数组。 S2:将结构体数组顺序写入到文件stuinfo.dat中。 S3:从stuinfo.dat中顺序读出学生信息,并输出。

  5. 任务10.1 将多个学生成绩单顺序读写到文件中 任务实现 根据上述的解决思路和相关知识点,具体程序实现如下: #define SIZE 3 struct student { char name[20]; char sex [3]; float score[SIZE]; }; struct student stu[SIZE]={{"肖飞","男",86,56,76},{"李雪","女",75,95,83}, {"郭键","男",91,89,61}}; void Save(struct student *pStu,char *fileName);

  6. 任务10.1 将多个学生成绩单顺序读写到文件中 任务实现 根据上述的解决思路和相关知识点,具体程序实现如下: void Read(char * fileName); void Output(struct student *pStu); void main() { char * fileName="stuInfo.dat"; Save(stu,fileName); Read(fileName); } void Output(struct student * pStu) { int i,j;

  7. 任务10.1 将多个学生成绩单顺序读写到文件中 任务实现 根据上述的解决思路和相关知识点,具体程序实现如下: for(i=0;i<SIZE;i++) { printf("%s\t%s\t",pStu->name,pStu->score); for( j=0;j<SIZE;j++) { printf("%3.0f\t",pStu->score[j]); } pStu++; printf("\n"); } } void Save(struct student *pStu,char *fileName)

  8. 任务10.1 将多个学生成绩单顺序读写到文件中 任务实现 根据上述的解决思路和相关知识点,具体程序实现如下: { FILE *fp; int i; if((fp=fopen(filename,"w"))==NULL) { printf("不能打开文件\n"); return; } for( i=0;i<SIZE;i++) { if(fwrite(pStu+i,sizeof(struct student),1,fp)!=1) {

  9. 任务10.1 将多个学生成绩单顺序读写到文件中 任务实现 根据上述的解决思路和相关知识点,具体程序实现如下: printf("文件写入错误\n"); break; } } fclose(fp); } void Read(char *fileName) { FILE *fp; int i; struct student stud[3];

  10. 任务10.1 将多个学生成绩单顺序读写到文件中 任务实现 根据上述的解决思路和相关知识点,具体程序实现如下: if((fp=fopen(filename,"r"))==NULL) { printf("不能打开文件\n"); return; } for(i=0;i<SIZE;i++) { fread(&stud[i],sizeof(struct student),1,fp); } fclose(fp); Output(stud); }

  11. 任务10.1 将多个学生成绩单顺序读写到文件中 10.1.1 文件的基本概念 所谓“文件”,一般指存储在外部介质上数据的集合。 (1)  ASCII文件。 (2) 二进制文件。

  12. 任务10.1 将多个学生成绩单顺序读写到文件中 10.1.1 文件的基本概念

  13. 任务10.1 将多个学生成绩单顺序读写到文件中 10.1.2 文件的打开与关闭 10.1.2.1 文件类型指针 定义一个文件类型的指针变量: (1) 语法。 FILE *指针变量名 例如: FILE *fp;

  14. 任务10.1 将多个学生成绩单顺序读写到文件中 10.1.2 文件的打开与关闭 10.1.2.1 文件类型指针 定义一个文件类型的指针变量: (2) 语义。 fp是一个指向FILE类型结构体的指针变量。可以使fp指向某一个文件的结构体变量,从而通过该结构体变量中的文件信息访问该文件。也就是说,通过文件指针变量能够找到与它相关的文件。通常,每个不同文件都应设不同的指针变量。 在对文件读写之前应该“打开”该文件,在文件使用介绍后应关闭该文件。

  15. 任务10.1 将多个学生成绩单顺序读写到文件中 10.1.2 文件的打开与关闭 10.1.2.2 文件的打开 ANSI C规定了标准输入输出函数库,用fopen()函数来实现打开文件。 (1) 语法。 fp=fopen(文件名,使用文件方式) 例如: FILE * fp; fp=fopen("abc.txt","w");

  16. 任务10.1 将多个学生成绩单顺序读写到文件中 10.1.2 文件的打开与关闭 10.1.2.2 文件的打开 ANSI C规定了标准输入输出函数库,用fopen()函数来实现打开文件。 (2) 语义。 表示要打开的名字为“abc.txt”的文件,使用方式为“写入”。fopen函数返回一个指向“abc.txt”文件的指针并赋给文件结构体指针fp,这样fp就指向了“abc.txt”文件。 在打开一个文件时,需要以下3个信息: 1) 需要打开的文件名,也就是准备访问的文件名字。 2) 使用文件的方式(“读”或“写”等)。 3) 让哪个指针变量指向被打开的文件。

  17. 任务10.1 将多个学生成绩单顺序读写到文件中 10.1.2 文件的打开与关闭 10.1.2.2 文件的打开 表10-1 使用文件的方式

  18. 任务10.1 将多个学生成绩单顺序读写到文件中 10.1.2 文件的打开与关闭 10.1.2.3 文件的关闭 用fclose函数关闭文件。 (1) 语法。 fclose(文件指针); 例如: fclose(文件指针);

  19. 任务10.1 将多个学生成绩单顺序读写到文件中 10.1.2 文件的打开与关闭 10.1.2.3 文件的关闭 用fclose函数关闭文件。 (2) 语义。 在前面打开文件时,把打开文件所带回的指针赋值给了fp,通过fp把该文件关闭,即fp不再指向该文件。 应该养成在程序终止之前关闭所有文件的习惯,如果不关闭文件,将会丢失数据。因为如前所述,在向文件写数据时,是先将数据输到缓冲区,待缓冲区充满后才正式输出给文件。如果当数据未充满缓冲区而程序结束运行,就会将缓冲区中的数据丢失。用fclose函数关闭文件,可以避免这个问题,它先把缓冲区中的数据输出到磁盘文件,然后才释放文件指针变量。 fclose函数也返回一个值,如果返回值为0,则表示顺利执行了文件的关闭操作;否则返回EOF(-1)。

  20. 任务10.1 将多个学生成绩单顺序读写到文件中 10.1.3 文件的顺序写入与读取 10.1.3.1 fputc 函数 (1) 语法。 fputc(字符常量/字符变量,文件指针); 例如: fputc(字符常量/字符变量,文件指针);

  21. 任务10.1 将多个学生成绩单顺序读写到文件中 10.1.3 文件的顺序写入与读取 10.1.3.1 fputc 函数 (2) 语义。 将字符(ch的值)输出到fp所指向的文件中。fputc函数也返回一个值:如果输出成功,则返回值就是输出的字符;如果输出失败,则返回一个EOF(-1)。EOF是在stdio.h文件中定义的符号常量,值为-1。

  22. 任务10.1 将多个学生成绩单顺序读写到文件中 10.1.3 文件的顺序写入与读取 10.1.3.2 fgetc 函数 (1) 语法。 字符变量=fgetc(fp) 例如: ch=fgetc(fp);

  23. 任务10.1 将多个学生成绩单顺序读写到文件中 10.1.3 文件的顺序写入与读取 10.1.3.2 fgetc 函数 (2) 语义。 从fp所指向的文件中读取一个字符并赋给字符变量ch。如果在执行fgetc读字符时遇到文件结束符,函数返回一个文件结束标志EOF(-1)。

  24. 任务10.1 将多个学生成绩单顺序读写到文件中 10.1.3 文件的顺序写入与读取 10.1.3.3 fread函数与fwrite函数 一个指针 fread(buffer,size,count,fp); fwrite(buffer,size,count,fp); 要进行读写多少个size字节的数据项 要读写的字节数

  25. 任务10.1 将多个学生成绩单顺序读写到文件中 10.1.3 文件的顺序写入与读取 10.1.3.3 fread函数与fwrite函数 【例10-2】从键盘上输入3个学生的信息,保存到文件“stu.dat”中,然后从文件中读取,并输出。 程序如下: #define SIZE 3 struct student { char name[10]; char sex [3]; int age; char address[20];

  26. 任务10.1 将多个学生成绩单顺序读写到文件中 10.1.3 文件的顺序写入与读取 10.1.3.3 fread函数与fwrite函数 }; struct student stu[SIZE]; void Save(char *fileName); void Read(char *fileName); void Output(struct student *pStu); void main() { char *fileName="stu.dat"; int I;

  27. 任务10.1 将多个学生成绩单顺序读写到文件中 10.1.3 文件的顺序写入与读取 10.1.3.3 fread函数与fwrite函数 printf("请输入三个学生的数据:姓名、性别、年龄与地址,数据用空格分隔\n"); for( i=0;i<SIZE;i++) { scanf("%s%s%d%s",&stu[i].name,&stu[i].sex,&stu[i].age,&stu[i].address); } Save(fileName); printf("学生数据已经保存\n"); printf("从文件中读出的学生数据为:\n");

  28. 任务10.1 将多个学生成绩单顺序读写到文件中 10.1.3 文件的顺序写入与读取 10.1.3.3 fread函数与fwrite函数 Read(fileName); } void Output(struct student *pStu) { int i; for(i=0;i<SIZE;i++) { printf("%s\t%s\t%d\t%s\n",pStu->name,pStu->sex,pStu->age,pStu->address); pStu++; }

  29. 任务10.1 将多个学生成绩单顺序读写到文件中 10.1.3 文件的顺序写入与读取 10.1.3.3 fread函数与fwrite函数 } void Save(char *fileName) { FILE *fp; int i; if((fp=fopen(filename,"w"))==NULL) { printf("不能打开文件\n"); return; } for(i=0;i<SIZE;i++)

  30. 任务10.1 将多个学生成绩单顺序读写到文件中 10.1.3 文件的顺序写入与读取 10.1.3.3 fread函数与fwrite函数 { if(fwrite(&stu[i],sizeof(struct student),1,fp)!=1) { printf("文件写入错误\n"); break; } } fclose(fp); }  void Read(char *fileName) {

  31. 任务10.1 将多个学生成绩单顺序读写到文件中 10.1.3 文件的顺序写入与读取 10.1.3.3 fread函数与fwrite函数 FILE *fp; int i; if((fp=fopen(filename,"r"))==NULL) { printf("不能打开文件\n"); return; } struct student stud[3]; for(i=0;i<SIZE;i++) { fread(&stud[i],sizeof(struct student),1,fp);

  32. 任务10.1 将多个学生成绩单顺序读写到文件中 10.1.3 文件的顺序写入与读取 10.1.3.3 fread函数与fwrite函数 } fclose(fp); Output(stud); }

  33. 任务10.1 将多个学生成绩单顺序读写到文件中 10.1.3 文件的顺序写入与读取 10.1.3.4 fprintf函数与fscanf函数

  34. 任务10.1 将多个学生成绩单顺序读写到文件中 10.1.3 文件的顺序写入与读取 10.1.3.4 fprintf函数与fscanf函数 例如: fprintf(fp,"%d,%4.2f",i,j); 它的作用是将整型变量i和实型变量j的值按%d和%4.2f的格式输出到fp指向的文件上。 fscanf(fp,“%d,%f”,&i,&j); 它的作用是将文件中一个整型数据和一个实型数据读出,整型数据给变量i,实型数据给变量j。

  35. 任务10.1 将多个学生成绩单顺序读写到文件中 10.1.3 文件的顺序写入与读取 10.1.3.4 fprintf函数与fscanf函数 【例10-3】格式化保存数据到文件中,并读出显示到屏幕上。 程序如下: void main() { char *fileName="file2.txt"; FILE *fp1,*fp2; int i; float j; if((fp1=fopen(filename,"w"))==NULL) { printf("打开文件错误\n");

  36. 任务10.1 将多个学生成绩单顺序读写到文件中 10.1.3 文件的顺序写入与读取 10.1.3.4 fprintf函数与fscanf函数 exit(0); } printf("请输入一个整型数据与一个实型数据,数据之间用逗号隔开\n"); scanf("%d,%f",&i,&j); fprintf(fp1,"%d,%6.2f",i,j); fclose(fp1); printf("输入的数据已保存到文件file2.txt中\n"); printf("文件file2.txt中的内容为:\n"); if((fp2=fopen(filename,"r"))==NULL) {

  37. 任务10.1 将多个学生成绩单顺序读写到文件中 10.1.3 文件的顺序写入与读取 10.1.3.4 fprintf函数与fscanf函数 printf("打开文件错误\n"); exit(0); } int i2; float j2; fscanf(fp2,"%d,%f",&i2,&j2); fclose(fp2); printf("%d,%6.2f\n",i2,j2); }

  38. 任务10.2 更新文件中的学生成绩信息 任务介绍 任务10.1已经把学生的成绩信息保存到了文件“stuinfo.dat”中。现要求把学生李雪的第二门成绩由95更改为85,并保存。 学生成绩信息如下: 肖飞男86 56 76 李雪女75 95 83 郭键男91 89 61 要求输出格式为: 学生成绩信息为: 肖飞男86 56 76 李雪女75 95 83 郭键男91 89 61 更新后的学生成绩信息为: 肖飞男86 56 76 李雪女75 85 83 郭键男91 89 61

  39. 任务10.2 更新文件中的学生成绩信息 解决思路 方法1: S1:从文件中读出所有学生成绩信息到结构体数组中。 S2:把结构体数组中李雪的第二门课程的成绩由95改为85。 S3:把结构体数组重新全部写入到文件中。 通过方法1的描述,可以发现此方法存在效率低下的问题。假如文件中保存有几十条,上百条甚至几千条学生成绩记录的话,为了修改其中一条记录,而不得不对全部的记录进行读写,将会对程序的执行效率有很大的影响。

  40. 任务10.2 更新文件中的学生成绩信息 解决思路 由上述的分析可知,采用方式1实现本任务是不科学的。现介绍一种新的方法,只需对文件中“李雪”这条的记录进行读写操作,而不会涉及其他无关的记录。 方法2: S1:从文件中读出学生李雪一条成绩信息到结构体中。 S2:把结构体中李雪的第二门课程的成绩由95改为85。 S3:把结构体重新写入到文件中。

  41. 任务10.2 更新文件中的学生成绩信息 任务实现 根据上述的解决思路和相关知识点,具体程序实现如下: #define SIZE 3 struct student { char name[20]; char sex [3]; float score[SIZE]; }; void Read(char *fileName); void Output(struct student *pStu); void RandomRead(char *filename,int i); /*随机读函数*/ void RandomWrite(char *filename,struct student stud,int i);

  42. 任务10.2 更新文件中的学生成绩信息 任务实现 根据上述的解决思路和相关知识点,具体程序实现如下: void main() { char *fileName="stuInfo.dat"; printf("学生成绩信息为:\n"); Read(fileName); RandomRead(filename,1); printf("更新后的学生成绩信息为:\n"); Read(fileName); } void Output(struct student *pStu) { int I;

  43. 任务10.2 更新文件中的学生成绩信息 任务实现 根据上述的解决思路和相关知识点,具体程序实现如下: for(i=0;i<SIZE;i++) { printf("%s\t%s\t",pStu->name,pStu->sex); for(int j=0;j<SIZE;j++) printf("%3.0f\t",pStu->score[j]); } pStu++; printf("\n"); } } void Read(char *fileName) {

  44. 任务10.2 更新文件中的学生成绩信息 任务实现 根据上述的解决思路和相关知识点,具体程序实现如下: FILE *fp; int i; struct student stud[3]; if((fp=fopen(filename,"r"))==NULL) { printf("不能打开文件\n"); return; } for( i=0;i<SIZE;i++) { fread(&stud[i],sizeof(struct student),1,fp);

  45. 任务10.2 更新文件中的学生成绩信息 任务实现 根据上述的解决思路和相关知识点,具体程序实现如下: } fclose(fp); Output(stud); } void RandomRead(char *filename,int i) { FILE *fp; struct student stud; if((fp=fopen(filename,"r+"))==NULL) { printf("不能打开文件\n"); return;

  46. 任务10.2 更新文件中的学生成绩信息 任务实现 根据上述的解决思路和相关知识点,具体程序实现如下: } fseek(fp,i*sizeof(struct student),0); fread(&stud,sizeof(struct student),1,fp); fclose(fp); stud.score[1]=85.0f; RandomWrite(filename,stud,i); } void RandomWrite(char *fileName,struct student stud,int i) { FILE *fp; if((fp=fopen(filename,"r+"))==NULL) {

  47. 任务10.2 更新文件中的学生成绩信息 任务实现 根据上述的解决思路和相关知识点,具体程序实现如下: printf("不能打开文件\n"); return; } fseek(fp,i*sizeof(struct student),0); if(fwrite(&stud,sizeof(struct student),1,fp)!=1) { printf("文件写入错误\n"); fclose(fp); return; } fclose(fp); }

  48. 任务10.2 更新文件中的学生成绩信息 10.2.1 文件的定位 10.2.1.1 rewind函数 (1) 语法。 rewind(文件指针); 例如: rewind(fp); (2) 语义。 使位置指针重新返回文件的开头。函数没有返回值。

  49. 任务10.2 更新文件中的学生成绩信息 10.2.1 文件的定位 10.2.1.2 fseek函数 (1) 语法。 fseek(文件指针,位移量,起始点); 例如: fseek(fp,sizeof(struct student),0);

  50. 任务10.2 更新文件中的学生成绩信息 10.2.1 文件的定位 10.2.1.2 fseek函数 (2) 语义。 “起始点”用0,1或2代替,0代表“文件开始”;1为“当前位置”;2为“文件末尾”。 “位移量”指以“起始点”为基点,向前移动的字节数。ANSI C和大多数C版本要求位移量是long型数据。这样当文件的长度大于64 K时不致出问题。ANSI C标准规定在数字的末尾加一个字母L,就表示是long型。 用fseek函数可以实现改变文件的位置指针。

More Related