C Primer Plus 第六版(中文版)第十四章(14.18.6)编程练习答案

多次修改终于可以了,数组清零少了Id、姓、名的清零
分部走:1、创建一个结构体数组,对数组进行清零,防止有无用数据
2、对文本信息进行读取,该球员无上场信息读取下一个球员信息
3、计算安打率
4、遍历显示读取的文本信息

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define LEN 19

typedef struct
{
    
    
    int id;          //球员的编号
    char fname[LEN]; //球员的名;
    char lname[LEN]; //球员的姓;
    int stage_num;   //球员的上场次数;
    int hit_num;     //球员的击中数;
    int base_num;    //球员的走垒数;
    int rbi;         //球员的打点;
    float hit_rate;  //球员的安打率;
} TEAM;

void clean_trash(TEAM players[], int n);
int read_datas(TEAM players[], int n, FILE *fp);
void count_hit_rate(TEAM players[], int n);
void show_messages(TEAM players[], int n);

int main(void)
{
    
    
    FILE *fp;
    int len;
    TEAM players[LEN];

    if ((fp = fopen("datas.txt", "r")) == NULL)
    {
    
    
        fprintf(stderr, "Can't open file datas.txt.\n");
        exit(EXIT_FAILURE);
    }
    clean_trash(players, LEN);          //为累计数据之和做准备,清理内存;
    len = read_datas(players, LEN, fp); //统计文件中不同球员的数量;
    count_hit_rate(players, LEN);
    show_messages(players, LEN);
    if (fclose(fp) != 0)
    {
    
    
        fprintf(stderr, "Can't close file datas.txt.\n");
        exit(EXIT_FAILURE);
    }

    return;
}

void clean_trash(TEAM players[], int n)
{
    
    
    int i;

    for (i = 0; i < n; i++) //原数组内容全部清零
    {
    
    
        players[i].id = 0;
        players[i].stage_num = 0;
        players[i].hit_num = 0;
        players[i].base_num = 0;
        players[i].rbi = 0;
        memset(players[i].fname, 0 , LEN);
        memset(players[i].lname, 0 , LEN);
    }
}

int read_datas(TEAM players[], int n, FILE *fp)
{
    
    
    int ch = 0;
    int count = 0;
    float hit_rate;
    char fname[LEN], lname[LEN];
    int m, stage_num, hit_num, base_num, rbi;

    //fscanf如果成功,该函数返回成功匹配和赋值的个数。如果到达文件末尾或发生读错误,则返回 EOF。
    count = fscanf(fp, "%d %18s %18s %d %d %d %d",
                   &m, fname, lname, &stage_num, &hit_num, &base_num, &rbi);

    while ((count == 7) && !feof(fp) && (ch < n))
    {
    
    
        if (players[m].stage_num == 0)//球员上场次数为0,就去访问下一个有效的球员信息数组
        {
    
    
            ch++;
        }

        players[m].id = m;
        strcpy(players[m].fname, fname); //把文本中的球员信息赋给m这个有效数组里去
        strcpy(players[m].lname, lname);
        players[m].stage_num += stage_num;
        players[m].hit_num += hit_num;
        players[m].base_num += base_num;
        players[m].rbi += rbi;
        //再次读取一下文本数据(有具体内容信息的数组)
        count = fscanf(fp, "%d %18s %18s %d %d %d %d",
                       &m, fname, lname, &stage_num, &hit_num, &base_num, &rbi);
    }
    return ch;
}

void count_hit_rate(TEAM players[], int n)
{
    
    
    int i;

    for (i = 0; i < n; i++)
    {
    
    
        players[i].hit_rate = (float)players[i].hit_num / (float)players[i].stage_num;
        //计算每个运动员的安打率;
    }
    return;
}

void show_messages(TEAM players[], int n)
{
    
    
    int i;

    printf("Datas for all players:\n");
    printf("Id   First_name   Last_name   Stage   Hit_rate   Base_num   RBI   Hit_rate\n");
    for (i = 0; i < n; i++)
    {
    
    
        printf("%d %12s %10s %5d %7d %11d %8d %8.2f\n",
               players[i].id, players[i].fname, players[i].lname,
               players[i].stage_num, players[i].hit_num, players[i].base_num,
               players[i].rbi, players[i].hit_rate);
    }
    return;
}

猜你喜欢

转载自blog.csdn.net/HanLongXia/article/details/108831016