鱼C论坛

 找回密码
 立即注册
查看: 2300|回复: 2

[已解决]文件一道题求助大佬急急急

[复制链接]
发表于 2020-12-4 11:38:33 | 显示全部楼层 |阅读模式
6鱼币
#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;

//从文件fileName表示的二进制文件中读取学生基本信息,
//包括学号、姓名、性别、出生日期,若干门课程的成绩
//文件的第一行存储的信息包含了n和m,即学生的人数和课程门数
void ReadStudInfo(const char *fileName, STUDENT stud[])
{
/*************Begin***************/




/*************End*****************/
}

//向文件fileName表示的二进制文件中写入学生基本信息,
//包括学号、姓名、性别、出生日期,若干门课程的成绩、总分、平均分、名次
//文件的第一行存储的信息应该包括n和m,即学生的人数和课程门数
void SaveResult(const char *fileName, STUDENT stud[],int n,int m)
{
/*************Begin***************/




/*************End*****************/
}


1.ReadStudInfo函数功能:实现从二进制文件中读取学生的基本信息。函数ReadStudInfo函数原型为:

void ReadStudInfo(const char *fileName, STUDENT stud[]);

其中:

参数fileName是一个二进制格式的文件,位于当前目录,即与源程序文件在同一文件夹下。文件中首先是以二进制数据形式写入的学生人数(整数n,不超过30)和课程数量(整数n,不超过5),然后是n个学生的信息,学生信息在结构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;

文件中存储了 total,average,rank 三项信息,但均为初始值0。
函数ReadStudInfo的第二个参数stud存放读取出来的学生信息。




而2.SaveResult函数功能:实现从二进制格式文件中读取学生的基本信息。函数SaveResult函数原型为:

void SaveResult(const char *fileName, STUDENT stud[],int n,int m);

其中:

参数fileName是一个二进制格式文件,位于当前目录,即与源程序文件在同一文件夹下。
文件中首先要求以二进制形式写入学生人数(整数n,不超过30)和课程数量(整数n,不超过5),然后是n个学生的信息。n个学生的信息存放在第二个参数stud开始的n个结构体数据单元中。
每个学生的信息包括学号、姓名、性别、出生日期,若干门课程的成绩、总分、平均分、名次。






最佳答案
2020-12-4 11:38:34
本帖最后由 jackz007 于 2020-12-6 13:24 编辑

        代码分为两个文件,分别对应两个程序,一个是 "save.c" 专门录入数据,另一个是 "load.c" 专门用来显示结果。两份代码除了 main() 不一样外,其它部分一模一样。

"save.c"
  1. #include <stdio.h>
  2. #include <stdlib.h>

  3. #define COURSE_MAXNUM 5

  4. //声明结构STUDENT
  5. struct student
  6. {
  7.     long studentID;
  8.     char studentName[20];
  9.     char sex[4];
  10.     struct{
  11.         int year;
  12.         int month;
  13.         int day;
  14.     }birthday;
  15.     float score[COURSE_MAXNUM];
  16.     float total;
  17.     float average;
  18.     int rank;
  19. };

  20. typedef struct student STUDENT;

  21. void swap(int * a , int * b)
  22. {
  23.         int t     ;
  24.         t = * a   ;
  25.         * a = * b ;
  26.         * b = t   ;
  27. }

  28. //从文件fileName表示的文本文件中读取学生基本信息,
  29. //包括学号、姓名、性别、出生日期,若干门课程的成绩
  30. //文件的第一行存储的信息包含了n和m,即学生的人数和课程门数
  31. void ReadStudInfo(const char * fileName , STUDENT stud[])
  32. {
  33. /***********Begin*****************/
  34.         FILE * fp                                                     ;
  35.         int m , n                                                     ;
  36.         if((fp = fopen(fileName , "rb")) != NULL) {
  37.                 fread(& m , sizeof(int) , 1 , fp)                     ;
  38.                 fread(& n , sizeof(int) , 1 , fp)                     ;
  39.                 fread(stud , sizeof(STUDENT) , m , fp)                ;
  40.                 fclose(fp)                                            ;
  41.         } else {
  42.                 fprintf(stderr , "\n")                                ;
  43.                 fprintf(stderr , "无法打开输入文件[%s]\n" , fileName) ;
  44.                 fprintf(stderr , "\n")                                ;
  45.         }
  46. /***********End*******************/
  47. }

  48. //向文件fileName表示的文本文件中写入学生基本信息,
  49. //包括学号、姓名、性别、出生日期,若干门课程的成绩、总分、平均分、名次
  50. //文件的第一行存储的信息应该包括n和m,即学生的人数和课程门数
  51. void SaveResult(const char *fileName, STUDENT stud[] , int n , int m)
  52. {
  53. /***********Begin*****************/
  54.         FILE * fp                                                      ;
  55.         if((fp = fopen(fileName , "wb")) != NULL) {
  56.                 fwrite(& m , sizeof(int) , 1 , fp)                     ;
  57.                 fwrite(& n , sizeof(int) , 1 , fp)                     ;
  58.                 fwrite(stud , sizeof(STUDENT) , m , fp)                ;
  59.                 fclose(fp)                                             ;
  60.         } else {
  61.                 fprintf(stderr , "\n")                                 ;
  62.                 fprintf(stderr , "无法打开输入文件[%s]\n" , fileName)  ;
  63.                 fprintf(stderr , "\n")                                 ;
  64.         }        
  65. /***********End*******************/
  66. }

  67. main(void)
  68. {
  69.         STUDENT d[50]                              ;
  70.         int m , n , j , k , rank                   ;
  71.         printf("请输入人数和课程门数 : ")          ;
  72.         scanf("%d%d" , & m , & n)                  ;
  73.         for(k = 0 ; k < m ; k ++) {
  74.                 printf("学号: ")                   ;
  75.                 scanf("%d" , & d[k] . studentID)   ;
  76.                 printf("姓名: ")          ;
  77.                 scanf("%s" , & d[k] . studentName) ;
  78.                 printf("性别: ")                   ;
  79.                 scanf("%s" , & d[k] . sex)         ;               
  80.                 printf("生日(yy mm dd): ")         ;
  81.                 scanf("%d%d%d" , & d[k] . birthday . year , & d[k] . birthday . month , & d[k] . birthday . day) ;               
  82.                 printf("%d 门课程的成绩 : " , n)   ;
  83.                 for(d[k] . total = 0 , j = 0 ; j < n ; j ++) {
  84.                         scanf("%f" , & d[k] . score[j])                                                          ;
  85.                         d[k] . total += d[k] . score[j]                                                          ;
  86.                 }
  87.                 d[k] . average = d[k] . total / n  ;
  88.                 d[k] . rank = 0                    ;
  89.         }
  90.         SaveResult("student.dat" , d , n , m)      ;
  91. }
复制代码

"load.c"
  1. #include <stdio.h>
  2. #include <stdlib.h>

  3. #define COURSE_MAXNUM 5

  4. //声明结构STUDENT
  5. struct student
  6. {
  7.     long studentID;
  8.     char studentName[20];
  9.     char sex[4];
  10.     struct{
  11.         int year;
  12.         int month;
  13.         int day;
  14.     }birthday;
  15.     float score[COURSE_MAXNUM];
  16.     float total;
  17.     float average;
  18.     int rank;
  19. };

  20. typedef struct student STUDENT;

  21. void swap(int * a , int * b)
  22. {
  23.         int t     ;
  24.         t = * a   ;
  25.         * a = * b ;
  26.         * b = t   ;
  27. }

  28. //从文件fileName表示的文本文件中读取学生基本信息,
  29. //包括学号、姓名、性别、出生日期,若干门课程的成绩
  30. //文件的第一行存储的信息包含了n和m,即学生的人数和课程门数
  31. void ReadStudInfo(const char * fileName , STUDENT stud[] , int * n , int * m)
  32. {
  33. /***********Begin*****************/
  34.         FILE * fp                                                     ;
  35.         if((fp = fopen(fileName , "rb")) != NULL) {
  36.                 fread(m , sizeof(int) , 1 , fp)                       ;
  37.                 fread(n , sizeof(int) , 1 , fp)                       ;
  38.                 fread(stud , sizeof(STUDENT) , * m , fp)              ;
  39.                 fclose(fp)                                            ;
  40.         } else {
  41.                 fprintf(stderr , "\n")                                ;
  42.                 fprintf(stderr , "无法打开输入文件[%s]\n" , fileName) ;
  43.                 fprintf(stderr , "\n")                                ;
  44.         }
  45. /***********End*******************/
  46. }

  47. //向文件fileName表示的文本文件中写入学生基本信息,
  48. //包括学号、姓名、性别、出生日期,若干门课程的成绩、总分、平均分、名次
  49. //文件的第一行存储的信息应该包括n和m,即学生的人数和课程门数
  50. void SaveResult(const char *fileName, STUDENT stud[] , int n , int m)
  51. {
  52. /***********Begin*****************/
  53.         FILE * fp                                                      ;
  54.         if((fp = fopen(fileName , "wb")) != NULL) {
  55.                 fwrite(& m , sizeof(int) , 1 , fp)                     ;
  56.                 fwrite(& n , sizeof(int) , 1 , fp)                     ;
  57.                 fwrite(stud , sizeof(STUDENT) , m , fp)                ;
  58.                 fclose(fp)                                             ;
  59.         } else {
  60.                 fprintf(stderr , "\n")                                 ;
  61.                 fprintf(stderr , "无法打开输入文件[%s]\n" , fileName)  ;
  62.                 fprintf(stderr , "\n")                                 ;
  63.         }        
  64. /***********End*******************/
  65. }

  66. main(void)
  67. {
  68.         STUDENT d[50]                               ;
  69.         int i , j , k , m , n , e[50]               ;
  70.         ReadStudInfo("student.dat" , d , & n , & m) ;
  71.         for(k = 0 ; k < m ; k ++) e[k] = k          ;
  72.         for(i = 0 ; i < m - 1 ; i ++) {
  73.                 for(j = i + 1 ; j < m ; j ++) {
  74.                         if(d[e[i]] . total < d[e[j]] . total) swap(& e[i] , & e[j]) ;
  75.                 }
  76.         }               
  77.         for(k = 0 ; k < m ; k ++) d[e[k]] . rank = k + 1                            ;
  78.         for(k = 0 ; k < m ; k ++) {
  79.                 printf("%d" , d[e[k]] . studentID)     ;
  80.                 printf(" %s" , d[e[k]] . studentName)  ;
  81.                 printf(" %s" , d[e[k]] . sex)          ;
  82.                 printf(" %4d-%02d-%02d" , d[e[k]] . birthday . year , d[e[k]] . birthday . month , d[e[k]] . birthday . day) ;
  83.                 printf(" %.0f" , d[e[k]] . score[0])                                                                         ;
  84.                 for(j = 1 ; j < n ; j ++) printf(" %.0f" , d[e[k]] . score[j])                                               ;
  85.                 printf(" %.0f %.0f %d\n" , d[e[k]] . total , d[e[k]] . average , d[e[k]] . rank)                             ;
  86.         }         
  87. }
复制代码

        注意,题目中 ReadStudInfo() 的定义存在严重缺陷:
  1. void ReadStudInfo(const char * fileName , STUDENT stud[])
复制代码

        因为学生人数和功课门数只能通过读文件内容才能获取,如果没有这两项关键数据,读出来的文件内容也无法处理,在函数定义中,并没有为传递这两项参数提供通道。所以,我把这个函数的定义修改成了:
  1. void ReadStudInfo(const char * fileName , STUDENT stud[] , int * n , int * m)
复制代码

        这里要强调的是,这个修改是必须的!
        编译、运行实况
  1. I:\00.2020\[00.00].Exercise\00.C\链表文件>g++ -o load load.c

  2. I:\00.2020\[00.00].Exercise\00.C\链表文件>load
  3. 20183004 任盈盈 女 2000-03-25 78 95 87 90 350 88 1
  4. 20183005 王仪琳 女 1999-08-01 92 83 72 92 339 85 2
  5. 20183002 林平之 男 2000-10-25 78 92 88 78 336 84 3
  6. 20183001 令狐冲 男 1999-09-01 90 83 72 82 327 82 4
  7. 20183003 岳灵珊 女 2001-12-01 89 72 98 66 325 81 5

  8. I:\00.2020\[00.00].Exercise\00.C\链表文件>
复制代码

最佳答案

查看完整内容

代码分为两个文件,分别对应两个程序,一个是 "save.c" 专门录入数据,另一个是 "load.c" 专门用来显示结果。两份代码除了 main() 不一样外,其它部分一模一样。 "save.c" "load.c" 注意,题目中 ReadStudInfo() 的定义存在严重缺陷: 因为学生人数和功课门数只能通过读文件内容才能获取,如果没有这两项关键数据,读出来的文件内容也无法处理,在函数定义中,并没有为传递这两项参数提供通道 ...
小甲鱼最新课程 -> https://ilovefishc.com
回复

使用道具 举报

发表于 2020-12-4 11:38:34 | 显示全部楼层    本楼为最佳答案   
本帖最后由 jackz007 于 2020-12-6 13:24 编辑

        代码分为两个文件,分别对应两个程序,一个是 "save.c" 专门录入数据,另一个是 "load.c" 专门用来显示结果。两份代码除了 main() 不一样外,其它部分一模一样。

"save.c"
  1. #include <stdio.h>
  2. #include <stdlib.h>

  3. #define COURSE_MAXNUM 5

  4. //声明结构STUDENT
  5. struct student
  6. {
  7.     long studentID;
  8.     char studentName[20];
  9.     char sex[4];
  10.     struct{
  11.         int year;
  12.         int month;
  13.         int day;
  14.     }birthday;
  15.     float score[COURSE_MAXNUM];
  16.     float total;
  17.     float average;
  18.     int rank;
  19. };

  20. typedef struct student STUDENT;

  21. void swap(int * a , int * b)
  22. {
  23.         int t     ;
  24.         t = * a   ;
  25.         * a = * b ;
  26.         * b = t   ;
  27. }

  28. //从文件fileName表示的文本文件中读取学生基本信息,
  29. //包括学号、姓名、性别、出生日期,若干门课程的成绩
  30. //文件的第一行存储的信息包含了n和m,即学生的人数和课程门数
  31. void ReadStudInfo(const char * fileName , STUDENT stud[])
  32. {
  33. /***********Begin*****************/
  34.         FILE * fp                                                     ;
  35.         int m , n                                                     ;
  36.         if((fp = fopen(fileName , "rb")) != NULL) {
  37.                 fread(& m , sizeof(int) , 1 , fp)                     ;
  38.                 fread(& n , sizeof(int) , 1 , fp)                     ;
  39.                 fread(stud , sizeof(STUDENT) , m , fp)                ;
  40.                 fclose(fp)                                            ;
  41.         } else {
  42.                 fprintf(stderr , "\n")                                ;
  43.                 fprintf(stderr , "无法打开输入文件[%s]\n" , fileName) ;
  44.                 fprintf(stderr , "\n")                                ;
  45.         }
  46. /***********End*******************/
  47. }

  48. //向文件fileName表示的文本文件中写入学生基本信息,
  49. //包括学号、姓名、性别、出生日期,若干门课程的成绩、总分、平均分、名次
  50. //文件的第一行存储的信息应该包括n和m,即学生的人数和课程门数
  51. void SaveResult(const char *fileName, STUDENT stud[] , int n , int m)
  52. {
  53. /***********Begin*****************/
  54.         FILE * fp                                                      ;
  55.         if((fp = fopen(fileName , "wb")) != NULL) {
  56.                 fwrite(& m , sizeof(int) , 1 , fp)                     ;
  57.                 fwrite(& n , sizeof(int) , 1 , fp)                     ;
  58.                 fwrite(stud , sizeof(STUDENT) , m , fp)                ;
  59.                 fclose(fp)                                             ;
  60.         } else {
  61.                 fprintf(stderr , "\n")                                 ;
  62.                 fprintf(stderr , "无法打开输入文件[%s]\n" , fileName)  ;
  63.                 fprintf(stderr , "\n")                                 ;
  64.         }        
  65. /***********End*******************/
  66. }

  67. main(void)
  68. {
  69.         STUDENT d[50]                              ;
  70.         int m , n , j , k , rank                   ;
  71.         printf("请输入人数和课程门数 : ")          ;
  72.         scanf("%d%d" , & m , & n)                  ;
  73.         for(k = 0 ; k < m ; k ++) {
  74.                 printf("学号: ")                   ;
  75.                 scanf("%d" , & d[k] . studentID)   ;
  76.                 printf("姓名: ")          ;
  77.                 scanf("%s" , & d[k] . studentName) ;
  78.                 printf("性别: ")                   ;
  79.                 scanf("%s" , & d[k] . sex)         ;               
  80.                 printf("生日(yy mm dd): ")         ;
  81.                 scanf("%d%d%d" , & d[k] . birthday . year , & d[k] . birthday . month , & d[k] . birthday . day) ;               
  82.                 printf("%d 门课程的成绩 : " , n)   ;
  83.                 for(d[k] . total = 0 , j = 0 ; j < n ; j ++) {
  84.                         scanf("%f" , & d[k] . score[j])                                                          ;
  85.                         d[k] . total += d[k] . score[j]                                                          ;
  86.                 }
  87.                 d[k] . average = d[k] . total / n  ;
  88.                 d[k] . rank = 0                    ;
  89.         }
  90.         SaveResult("student.dat" , d , n , m)      ;
  91. }
复制代码

"load.c"
  1. #include <stdio.h>
  2. #include <stdlib.h>

  3. #define COURSE_MAXNUM 5

  4. //声明结构STUDENT
  5. struct student
  6. {
  7.     long studentID;
  8.     char studentName[20];
  9.     char sex[4];
  10.     struct{
  11.         int year;
  12.         int month;
  13.         int day;
  14.     }birthday;
  15.     float score[COURSE_MAXNUM];
  16.     float total;
  17.     float average;
  18.     int rank;
  19. };

  20. typedef struct student STUDENT;

  21. void swap(int * a , int * b)
  22. {
  23.         int t     ;
  24.         t = * a   ;
  25.         * a = * b ;
  26.         * b = t   ;
  27. }

  28. //从文件fileName表示的文本文件中读取学生基本信息,
  29. //包括学号、姓名、性别、出生日期,若干门课程的成绩
  30. //文件的第一行存储的信息包含了n和m,即学生的人数和课程门数
  31. void ReadStudInfo(const char * fileName , STUDENT stud[] , int * n , int * m)
  32. {
  33. /***********Begin*****************/
  34.         FILE * fp                                                     ;
  35.         if((fp = fopen(fileName , "rb")) != NULL) {
  36.                 fread(m , sizeof(int) , 1 , fp)                       ;
  37.                 fread(n , sizeof(int) , 1 , fp)                       ;
  38.                 fread(stud , sizeof(STUDENT) , * m , fp)              ;
  39.                 fclose(fp)                                            ;
  40.         } else {
  41.                 fprintf(stderr , "\n")                                ;
  42.                 fprintf(stderr , "无法打开输入文件[%s]\n" , fileName) ;
  43.                 fprintf(stderr , "\n")                                ;
  44.         }
  45. /***********End*******************/
  46. }

  47. //向文件fileName表示的文本文件中写入学生基本信息,
  48. //包括学号、姓名、性别、出生日期,若干门课程的成绩、总分、平均分、名次
  49. //文件的第一行存储的信息应该包括n和m,即学生的人数和课程门数
  50. void SaveResult(const char *fileName, STUDENT stud[] , int n , int m)
  51. {
  52. /***********Begin*****************/
  53.         FILE * fp                                                      ;
  54.         if((fp = fopen(fileName , "wb")) != NULL) {
  55.                 fwrite(& m , sizeof(int) , 1 , fp)                     ;
  56.                 fwrite(& n , sizeof(int) , 1 , fp)                     ;
  57.                 fwrite(stud , sizeof(STUDENT) , m , fp)                ;
  58.                 fclose(fp)                                             ;
  59.         } else {
  60.                 fprintf(stderr , "\n")                                 ;
  61.                 fprintf(stderr , "无法打开输入文件[%s]\n" , fileName)  ;
  62.                 fprintf(stderr , "\n")                                 ;
  63.         }        
  64. /***********End*******************/
  65. }

  66. main(void)
  67. {
  68.         STUDENT d[50]                               ;
  69.         int i , j , k , m , n , e[50]               ;
  70.         ReadStudInfo("student.dat" , d , & n , & m) ;
  71.         for(k = 0 ; k < m ; k ++) e[k] = k          ;
  72.         for(i = 0 ; i < m - 1 ; i ++) {
  73.                 for(j = i + 1 ; j < m ; j ++) {
  74.                         if(d[e[i]] . total < d[e[j]] . total) swap(& e[i] , & e[j]) ;
  75.                 }
  76.         }               
  77.         for(k = 0 ; k < m ; k ++) d[e[k]] . rank = k + 1                            ;
  78.         for(k = 0 ; k < m ; k ++) {
  79.                 printf("%d" , d[e[k]] . studentID)     ;
  80.                 printf(" %s" , d[e[k]] . studentName)  ;
  81.                 printf(" %s" , d[e[k]] . sex)          ;
  82.                 printf(" %4d-%02d-%02d" , d[e[k]] . birthday . year , d[e[k]] . birthday . month , d[e[k]] . birthday . day) ;
  83.                 printf(" %.0f" , d[e[k]] . score[0])                                                                         ;
  84.                 for(j = 1 ; j < n ; j ++) printf(" %.0f" , d[e[k]] . score[j])                                               ;
  85.                 printf(" %.0f %.0f %d\n" , d[e[k]] . total , d[e[k]] . average , d[e[k]] . rank)                             ;
  86.         }         
  87. }
复制代码

        注意,题目中 ReadStudInfo() 的定义存在严重缺陷:
  1. void ReadStudInfo(const char * fileName , STUDENT stud[])
复制代码

        因为学生人数和功课门数只能通过读文件内容才能获取,如果没有这两项关键数据,读出来的文件内容也无法处理,在函数定义中,并没有为传递这两项参数提供通道。所以,我把这个函数的定义修改成了:
  1. void ReadStudInfo(const char * fileName , STUDENT stud[] , int * n , int * m)
复制代码

        这里要强调的是,这个修改是必须的!
        编译、运行实况
  1. I:\00.2020\[00.00].Exercise\00.C\链表文件>g++ -o load load.c

  2. I:\00.2020\[00.00].Exercise\00.C\链表文件>load
  3. 20183004 任盈盈 女 2000-03-25 78 95 87 90 350 88 1
  4. 20183005 王仪琳 女 1999-08-01 92 83 72 92 339 85 2
  5. 20183002 林平之 男 2000-10-25 78 92 88 78 336 84 3
  6. 20183001 令狐冲 男 1999-09-01 90 83 72 82 327 82 4
  7. 20183003 岳灵珊 女 2001-12-01 89 72 98 66 325 81 5

  8. I:\00.2020\[00.00].Exercise\00.C\链表文件>
复制代码
小甲鱼最新课程 -> https://ilovefishc.com
回复

使用道具 举报

 楼主| 发表于 2020-12-8 16:46:34 | 显示全部楼层
jackz007 发表于 2020-12-6 11:20
代码分为两个文件,分别对应两个程序,一个是 "save.c" 专门录入数据,另一个是 "load.c" 专门用来 ...

哦哦好的大佬已经解决了谢谢啦
小甲鱼最新课程 -> https://ilovefishc.com
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Archiver|鱼C工作室 ( 粤ICP备18085999号-1 | 粤公网安备 44051102000585号)

GMT+8, 2025-4-27 03:01

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表