|
|
发表于 2020-12-4 11:38:34
|
显示全部楼层
本帖最后由 jackz007 于 2020-12-6 13:24 编辑
代码分为两个文件,分别对应两个程序,一个是 "save.c" 专门录入数据,另一个是 "load.c" 专门用来显示结果。两份代码除了 main() 不一样外,其它部分一模一样。
"save.c"
- #include <stdio.h>
- #include <stdlib.h>
- #define COURSE_MAXNUM 5
- //声明结构STUDENT
- struct student
- {
- long studentID;
- char studentName[20];
- char sex[4];
- struct{
- int year;
- int month;
- int day;
- }birthday;
- float score[COURSE_MAXNUM];
- float total;
- float average;
- int rank;
- };
- typedef struct student STUDENT;
- void swap(int * a , int * b)
- {
- int t ;
- t = * a ;
- * a = * b ;
- * b = t ;
- }
- //从文件fileName表示的文本文件中读取学生基本信息,
- //包括学号、姓名、性别、出生日期,若干门课程的成绩
- //文件的第一行存储的信息包含了n和m,即学生的人数和课程门数
- void ReadStudInfo(const char * fileName , STUDENT stud[])
- {
- /***********Begin*****************/
- FILE * fp ;
- int m , n ;
- if((fp = fopen(fileName , "rb")) != NULL) {
- fread(& m , sizeof(int) , 1 , fp) ;
- fread(& n , sizeof(int) , 1 , fp) ;
- fread(stud , sizeof(STUDENT) , m , fp) ;
- fclose(fp) ;
- } else {
- fprintf(stderr , "\n") ;
- fprintf(stderr , "无法打开输入文件[%s]\n" , fileName) ;
- fprintf(stderr , "\n") ;
- }
- /***********End*******************/
- }
- //向文件fileName表示的文本文件中写入学生基本信息,
- //包括学号、姓名、性别、出生日期,若干门课程的成绩、总分、平均分、名次
- //文件的第一行存储的信息应该包括n和m,即学生的人数和课程门数
- void SaveResult(const char *fileName, STUDENT stud[] , int n , int m)
- {
- /***********Begin*****************/
- FILE * fp ;
- if((fp = fopen(fileName , "wb")) != NULL) {
- fwrite(& m , sizeof(int) , 1 , fp) ;
- fwrite(& n , sizeof(int) , 1 , fp) ;
- fwrite(stud , sizeof(STUDENT) , m , fp) ;
- fclose(fp) ;
- } else {
- fprintf(stderr , "\n") ;
- fprintf(stderr , "无法打开输入文件[%s]\n" , fileName) ;
- fprintf(stderr , "\n") ;
- }
- /***********End*******************/
- }
- main(void)
- {
- STUDENT d[50] ;
- int m , n , j , k , rank ;
- printf("请输入人数和课程门数 : ") ;
- scanf("%d%d" , & m , & n) ;
- for(k = 0 ; k < m ; k ++) {
- printf("学号: ") ;
- scanf("%d" , & d[k] . studentID) ;
- printf("姓名: ") ;
- scanf("%s" , & d[k] . studentName) ;
- printf("性别: ") ;
- scanf("%s" , & d[k] . sex) ;
- printf("生日(yy mm dd): ") ;
- scanf("%d%d%d" , & d[k] . birthday . year , & d[k] . birthday . month , & d[k] . birthday . day) ;
- printf("%d 门课程的成绩 : " , n) ;
- for(d[k] . total = 0 , j = 0 ; j < n ; j ++) {
- scanf("%f" , & d[k] . score[j]) ;
- d[k] . total += d[k] . score[j] ;
- }
- d[k] . average = d[k] . total / n ;
- d[k] . rank = 0 ;
- }
- SaveResult("student.dat" , d , n , m) ;
- }
复制代码
"load.c"
- #include <stdio.h>
- #include <stdlib.h>
- #define COURSE_MAXNUM 5
- //声明结构STUDENT
- struct student
- {
- long studentID;
- char studentName[20];
- char sex[4];
- struct{
- int year;
- int month;
- int day;
- }birthday;
- float score[COURSE_MAXNUM];
- float total;
- float average;
- int rank;
- };
- typedef struct student STUDENT;
- void swap(int * a , int * b)
- {
- int t ;
- t = * a ;
- * a = * b ;
- * b = t ;
- }
- //从文件fileName表示的文本文件中读取学生基本信息,
- //包括学号、姓名、性别、出生日期,若干门课程的成绩
- //文件的第一行存储的信息包含了n和m,即学生的人数和课程门数
- void ReadStudInfo(const char * fileName , STUDENT stud[] , int * n , int * m)
- {
- /***********Begin*****************/
- FILE * fp ;
- if((fp = fopen(fileName , "rb")) != NULL) {
- fread(m , sizeof(int) , 1 , fp) ;
- fread(n , sizeof(int) , 1 , fp) ;
- fread(stud , sizeof(STUDENT) , * m , fp) ;
- fclose(fp) ;
- } else {
- fprintf(stderr , "\n") ;
- fprintf(stderr , "无法打开输入文件[%s]\n" , fileName) ;
- fprintf(stderr , "\n") ;
- }
- /***********End*******************/
- }
- //向文件fileName表示的文本文件中写入学生基本信息,
- //包括学号、姓名、性别、出生日期,若干门课程的成绩、总分、平均分、名次
- //文件的第一行存储的信息应该包括n和m,即学生的人数和课程门数
- void SaveResult(const char *fileName, STUDENT stud[] , int n , int m)
- {
- /***********Begin*****************/
- FILE * fp ;
- if((fp = fopen(fileName , "wb")) != NULL) {
- fwrite(& m , sizeof(int) , 1 , fp) ;
- fwrite(& n , sizeof(int) , 1 , fp) ;
- fwrite(stud , sizeof(STUDENT) , m , fp) ;
- fclose(fp) ;
- } else {
- fprintf(stderr , "\n") ;
- fprintf(stderr , "无法打开输入文件[%s]\n" , fileName) ;
- fprintf(stderr , "\n") ;
- }
- /***********End*******************/
- }
- main(void)
- {
- STUDENT d[50] ;
- int i , j , k , m , n , e[50] ;
- ReadStudInfo("student.dat" , d , & n , & m) ;
- for(k = 0 ; k < m ; k ++) e[k] = k ;
- for(i = 0 ; i < m - 1 ; i ++) {
- for(j = i + 1 ; j < m ; j ++) {
- if(d[e[i]] . total < d[e[j]] . total) swap(& e[i] , & e[j]) ;
- }
- }
- for(k = 0 ; k < m ; k ++) d[e[k]] . rank = k + 1 ;
- for(k = 0 ; k < m ; k ++) {
- printf("%d" , d[e[k]] . studentID) ;
- printf(" %s" , d[e[k]] . studentName) ;
- printf(" %s" , d[e[k]] . sex) ;
- printf(" %4d-%02d-%02d" , d[e[k]] . birthday . year , d[e[k]] . birthday . month , d[e[k]] . birthday . day) ;
- printf(" %.0f" , d[e[k]] . score[0]) ;
- for(j = 1 ; j < n ; j ++) printf(" %.0f" , d[e[k]] . score[j]) ;
- printf(" %.0f %.0f %d\n" , d[e[k]] . total , d[e[k]] . average , d[e[k]] . rank) ;
- }
- }
复制代码
注意,题目中 ReadStudInfo() 的定义存在严重缺陷:
- void ReadStudInfo(const char * fileName , STUDENT stud[])
复制代码
因为学生人数和功课门数只能通过读文件内容才能获取,如果没有这两项关键数据,读出来的文件内容也无法处理,在函数定义中,并没有为传递这两项参数提供通道。所以,我把这个函数的定义修改成了:
- void ReadStudInfo(const char * fileName , STUDENT stud[] , int * n , int * m)
复制代码
这里要强调的是,这个修改是必须的!
编译、运行实况
- I:\00.2020\[00.00].Exercise\00.C\链表文件>g++ -o load load.c
- I:\00.2020\[00.00].Exercise\00.C\链表文件>load
- 20183004 任盈盈 女 2000-03-25 78 95 87 90 350 88 1
- 20183005 王仪琳 女 1999-08-01 92 83 72 92 339 85 2
- 20183002 林平之 男 2000-10-25 78 92 88 78 336 84 3
- 20183001 令狐冲 男 1999-09-01 90 83 72 82 327 82 4
- 20183003 岳灵珊 女 2001-12-01 89 72 98 66 325 81 5
- I:\00.2020\[00.00].Exercise\00.C\链表文件>
复制代码 |
|