学习笔记 按格式读写文件存取学生信息

任务描述

本关要求编写函数ReadStudInfoSaveResult

编程要求

本关的编程任务是补全step2/fileTxt.c文件中ReadStudInfo函数和SaveResult函数,以实现按格式使用FILE结构存取学生信息的功能。具体要求如下: 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 三项信息。
  • 函数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个结构体数据单元中。
  • 每个学生的信息包括学号、姓名、性别、出生日期,若干门课程的成绩、总分、平均分、名次。

测试说明

本关的测试文件是step2/main.c,其中将会调用你在step2/fileTxt.c文件中完成的ReadStudInfo函数和SaveResult函数。除此之后,step2/main.c中还对学生信息进行了处理:包括计算总分、平均分和名次。其次还实现了输入测试数据、输出测试结果、写入测试文件(student.txt)、读取测试文件(result.txt):

1.调用函数Input()将标准输入的数据读入内存,然后调用SaveStudInfo()函数将数据再写入到student.txt文本文件,以便为**ReadStudInfo()**函数从文本文件读取学生信息准备测试数据。

2.调用函数ReadResult()SaveResult()函数保存的result.txt中的学生信息读入内存,并调用Print()函数进行输出。**SaveResult()**函数需要将计算出总分、平均分和名次信息的学生信息存入result.txt

3.student.txt的示例如下:

4.result.txt的示例如下:

平台会对你编写的代码进行测试: 测试样例:

测试输入

5 4

20183001 令狐冲 男 1999-09-01 90 83 72 82

20183002 林平之 男 2000-10-25 78 92 88 78

20183003 岳灵珊 女 2001-12-01 89 72 98 66

20183004 任盈盈 女 2000-03-25 78 95 87 90

20183005 王仪琳 女 1999-08-01 92 83 72 92

预期输出

 NO.          Name Sex   Birthday   Computer   English      Math     Music     Total   Average Rank
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

代码实现

//main.cpp
#define _CRT_SECURE_NO_WARNINGS 1
#include <iostream>
using namespace std;

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <assert.h>
#include <errno.h>
#define COURSE_MAXNUM 5

//定义结构体
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;

//外文件
extern void ReadStudInfo(const char* fileName, STUDENT stud[]);//读取文件中的初始信息
extern void SaveResult(const char* fileName, STUDENT stud[], int n, int m);//保存排名之后的信息到文件夹中

void Input(STUDENT* stud, int n, int m);//输入信息到结构体中
void Print(STUDENT* stud, int n, int m);//打印到屏幕上
void TotalAndAverage(STUDENT* stud, int n, int m);//求总分和平均分
void RankByTotal(STUDENT* stud, int n, int m);//计算排名
void SaveStudInfo(const char* fileName, STUDENT* stud, int n, int m);//保存初始信息到文件中
void ReadResult(const char* fileName, STUDENT* stud);//读取排名后的文件信息

int main()
{
    int n, m;
    STUDENT* stud = NULL;

    (void)scanf("%d %d", &n, &m);

    stud = (STUDENT*)malloc(n * sizeof(STUDENT));
    if (NULL == stud)
    {
        printf("%s", strerror(errno));
        return 0;
    }
    Input(stud, n, m);

    SaveStudInfo("student.txt", stud, n, m);
    free(stud);
    stud = NULL;

    stud = (STUDENT*)malloc(n * sizeof(STUDENT));
    if (NULL == stud)
    {
        printf("%s", strerror(errno));
        return 0;
    }
    ReadStudInfo("student.txt", stud);

    TotalAndAverage(stud, n, m);

    RankByTotal(stud, n, m);

    SaveResult("result.txt", stud, n, m);
    free(stud);
    stud = NULL;


    stud = (STUDENT*)malloc(n * sizeof(STUDENT));
    if (NULL == stud)
    {
        printf("%s", strerror(errno));
        return 0;
    }
    ReadResult("result.txt", stud);

    Print(stud, n, m);

    free(stud);
    stud = NULL;
    return 0;
}

void Input(STUDENT* stud, int n, int m)
{
    int i = 0;
    for (i = 0; i < n; i++)
    {
        (void)scanf("%ld", &stud[i].studentID);
        (void)scanf("%s", stud[i].studentName);
        (void)scanf("%s", stud[i].sex);
        (void)scanf("%d-%d-%d", &stud[i].birthday.year, &stud[i].birthday.month, &stud[i].birthday.day);
        for (int j = 0; j < m; j++)
            (void)scanf("%f", &stud[i].score[j]);
        stud[i].total = 0;
        stud[i].average = 0;
        stud[i].rank = 0;
    }
}
void Print(STUDENT* stud, int n, int m)
{
    printf("%8s%12s%4s%12s%10s%10s%10s%10s%10s%10s%5s\n",
        "  NO.  ", "Name", "Sex", " Birthday ", "Computer", "English", "Math", "Music", "Total", "Average", "Rank");
    for (int i = 0; i < n; i++)
    {
        printf("%8ld", stud[i].studentID);
        printf("%15s", stud[i].studentName);
        printf("%5s", stud[i].sex);
        printf("%6d-%02d-%02d", stud[i].birthday.year, stud[i].birthday.month, stud[i].birthday.day);
        for (int j = 0; j < m; j++)
        {
            printf("%10.0f", stud[i].score[j]);
        }
        printf("%10.0f", stud[i].total);
        printf("%10.0f", stud[i].average);
        printf("%5d\n", stud[i].rank);
    }
}

void TotalAndAverage(STUDENT* stud, int n, int m)
{
    for (int i = 0; i < n; i++)
    {
        stud[i].total = 0;
        for (int j = 0; j < m; j++)
            stud[i].total += stud[i].score[j];

        stud[i].average = stud[i].total / 4;
    }
}

void RankByTotal(STUDENT* stud, int n, int m)
{

    for (int i = 0; i < n - 1; i++)
    {
        int k = i;
        for (int j = i + 1; j < n; j++)
        {
            if (stud[j].total > stud[k].total)
            {
                k = j;
            }
        }
        if (k != i)
        {
            STUDENT temp = stud[i];
            stud[i] = stud[k];
            stud[k] = temp;
        }
        stud[i].rank = i + 1;
        if (i > 0 && stud[i].total == stud[i - 1].total)
            stud[i].rank = stud[i - 1].rank;
    }
    stud[n - 1].rank = n;
    if (n - 1 > 0 && stud[n - 1].total == stud[n - 2].total)
        stud[n - 1].rank = stud[n - 2].rank;
}

void SaveStudInfo(const char* fileName, STUDENT* stud, int n, int m)
{
    FILE* fp = fopen(fileName, "w");
    if (fp == NULL)
    {
        printf("Failure to open %s!\n", fileName);
        exit(0);
    }
    fprintf(fp, "%d %d", n, m);

    for (int i = 0; i < n; i++)
    {
        fprintf(fp, "\n%-12ld\t", stud[i].studentID);
        fprintf(fp, "%-12s\t", stud[i].studentName);
        fprintf(fp, "%-4s\t", stud[i].sex);
        fprintf(fp, "%4d-%02d-%02d\t", stud[i].birthday.year, stud[i].birthday.month, stud[i].birthday.day);
        for (int j = 0; j < m; j++)
            fprintf(fp, "%.0f\t", stud[i].score[j]);
    }
    fclose(fp);
}


void ReadResult(const char* fileName, STUDENT* stud)
{
    FILE* fp = fopen(fileName, "r");
    if (fp == NULL)
    {
        printf("Failure to open %s!\n", fileName);
        exit(0);
    }
    int n, m;
    (void)fscanf(fp, "%d%d", &n, &m);
    for (int i = 0; i < n; i++)
    {
        (void)fscanf(fp, "%ld", &stud[i].studentID);
        (void)fscanf(fp, "%s", stud[i].studentName);
        (void)fscanf(fp, "%s", stud[i].sex);
        (void)fscanf(fp, "%d-%d-%d", &stud[i].birthday.year, &stud[i].birthday.month, &stud[i].birthday.day);
        for (int j = 0; j < m; j++)
            (void)fscanf(fp, "%f", &stud[i].score[j]);
        (void)fscanf(fp, "%f", &stud[i].total);
        (void)fscanf(fp, "%f", &stud[i].average);
        (void)fscanf(fp, "%d", &stud[i].rank);
    }
    fclose(fp);
}
//filetxt.cpp
#define _CRT_SECURE_NO_WARNINGS 1
#include <iostream>
using namespace std;


#include <stdio.h>
#include <stdlib.h>
#define COURSE_MAXNUM 5
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 ReadStudInfo(const char* fileName, STUDENT stud[]);
void SaveResult(const char* fileName, STUDENT stud[], int n, int m);

void ReadStudInfo(const char* fileName, STUDENT stud[])
{
    FILE* fp = fopen(fileName, "rb");
    if (fp == NULL)
    {
        printf("Failure to open %s!\n", fileName);
        exit(0);
    }
    int n = 0, m = 0;
    (void)fscanf(fp, "%d%d", &n, &m);
    for (int i = 0; i < n; i++)
    {
        (void)fscanf(fp, "%ld", &stud[i].studentID);
        (void)fscanf(fp, "%s", stud[i].studentName);
        (void)fscanf(fp, "%s", stud[i].sex);
        (void)fscanf(fp, "%d-%d-%d", &stud[i].birthday.year, &stud[i].birthday.month, &stud[i].birthday.day);
        for (int j = 0; j < m; j++)
            (void)fscanf(fp, "%f", &stud[i].score[j]);
    }
    fclose(fp);
}

void SaveResult(const char* fileName, STUDENT stud[], int n, int m)
{
    FILE* fp = fopen(fileName, "wb");
    if (fp == NULL)
    {
        printf("Failure to open %s!\n", fileName);
        exit(0);
    }
    fprintf(fp, "%d %d", n, m);

    for (int i = 0; i < n; i++)
    {
        fprintf(fp, "\n%-12ld\t", stud[i].studentID);
        fprintf(fp, "%-12s\t", stud[i].studentName);
        fprintf(fp, "%-4s\t", stud[i].sex);
        fprintf(fp, "%4d-%02d-%02d\t", stud[i].birthday.year, stud[i].birthday.month, stud[i].birthday.day);
        for (int j = 0; j < m; j++)
            fprintf(fp, "%.0f\t", stud[i].score[j]);
        fprintf(fp, "%.0f\t", stud[i].total);
        fprintf(fp, "%.0f\t", stud[i].average);
        fprintf(fp, "%d", stud[i].rank);
    }
    fclose(fp);
}

  • 5
    点赞
  • 48
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值