You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

基于WHILE循环与SWITCH结构的菜单驱动学生统计应用开发求助

学生统计菜单驱动程序实现问题及解决方案

问题描述

我正在实现一个基于WHILE循环和SWITCH选择结构的菜单驱动应用,需要完成读取StudentData.txt学生数据、计算平均分、展示数据、保存图表等功能。目前已搭建好代码框架,但核心函数尚未实现,同时存在以下疑问:

核心疑问

  • 如何使用ESG206B数组?
  • 无法完成Read_Data、Calculate_StudentAverage、Display_Data、Write_Graph函数的定义
  • 对Write_Graph函数的参数类型使用存在困惑

现有代码框架

#include <stdio.h>
#include <stdlib.h>
#include <conio.h>  // 用于getch()

#define Size_MainFuncArray 5            // 常量

// StudentData.txt中的数据格式:
// Jane 55 51 78
// Lungelo 69 84 75
// Greg 51 44 52
// Thando 23 78 61
// Bret 44 33 29
struct Student {
    char StudentName[10];
    int StudentMarks[3];
    float StudentAverage;
};

typedef struct Student Student;

// 函数声明
int DisplayMenu(void);
void Read_Data(Student Arr[], int Size);
void Calculate_StudentAverage(Student Arr[], int Size);
void Display_Data(Student Arr[], int Size);
void Write_Graph(Student Arr[], int Size);

// 主函数
int main(void)
{
    int choice;
    Student ESG206B[Size_MainFuncArray];    // 存储学生数据的数组

    while (1) {
        choice = DisplayMenu();

        switch (choice) {
            case 1:
                Read_Data(ESG206B, Size_MainFuncArray);
                Calculate_StudentAverage(ESG206B, Size_MainFuncArray);
                printf("数据加载及平均分计算完成!\n");
                break;
            case 2:
                Display_Data(ESG206B, Size_MainFuncArray);
                break;
            case 3:
                Write_Graph(ESG206B, Size_MainFuncArray);
                printf("图表已保存到Graph.txt!\n");
                break;
            case 4:
                printf("程序退出!\n");
                exit(0);
            default:
                printf("无效选项,请重新选择!\n");
        }

        printf("\nPress any key to continue...\n");
        getch();
        system("cls");
    }

    return 0;
}

// 显示菜单函数
int DisplayMenu(void)
{
    int Select;

    printf("************************************\n");
    printf("*    Welcome to Student Stats      *\n");
    printf("*    Student Number: 123456789     *\n");
    printf("************************************\n");

    printf("\n1. Load Data and Calculate Average\n");
    printf("2. Display Student Data\n");  // 修正拼写错误Dispaly->Display
    printf("3. Save Graph\n");
    printf("4. Exit\n");
    printf("Choice: ");
    fflush(stdin);
    scanf("%d", &Select);

    return Select;
}

核心函数实现及疑问解答

1. ESG206B数组的使用

ESG206B是Student类型的数组,大小为Size_MainFuncArray(5),用于存储从文件读取的所有学生数据。在主函数中,你需要将它作为参数传递给各个核心函数,让函数可以操作数组中的学生数据,比如Read_Data(ESG206B, Size_MainFuncArray)就是将数组传入读取数据的函数。

2. 核心函数实现

// 读取StudentData.txt中的学生数据
void Read_Data(Student Arr[], int Size)
{
    FILE *fp = fopen("StudentData.txt", "r");
    if (fp == NULL) {
        printf("无法打开StudentData.txt文件!\n");
        return;
    }

    for (int i = 0; i < Size; i++) {
        // 读取姓名和三个分数
        fscanf(fp, "%s %d %d %d", 
               Arr[i].StudentName, 
               &Arr[i].StudentMarks[0], 
               &Arr[i].StudentMarks[1], 
               &Arr[i].StudentMarks[2]);
    }

    fclose(fp);
}

// 计算每个学生的平均分
void Calculate_StudentAverage(Student Arr[], int Size)
{
    for (int i = 0; i < Size; i++) {
        int total = Arr[i].StudentMarks[0] + Arr[i].StudentMarks[1] + Arr[i].StudentMarks[2];
        Arr[i].StudentAverage = total / 3.0f;  // 用3.0f确保浮点除法
    }
}

// 展示所有学生数据
void Display_Data(Student Arr[], int Size)
{
    printf("-----------------------------------------\n");
    printf("姓名\t分数1\t分数2\t分数3\t平均分\n");
    printf("-----------------------------------------\n");
    for (int i = 0; i < Size; i++) {
        printf("%s\t%d\t%d\t%d\t%.2f\n", 
               Arr[i].StudentName, 
               Arr[i].StudentMarks[0], 
               Arr[i].StudentMarks[1], 
               Arr[i].StudentMarks[2], 
               Arr[i].StudentAverage);
    }
    printf("-----------------------------------------\n");
}

// 将平均分柱状图写入Graph.txt
void Write_Graph(Student Arr[], int Size)
{
    FILE *fp = fopen("Graph.txt", "w");
    if (fp == NULL) {
        printf("无法创建Graph.txt文件!\n");
        return;
    }

    fprintf(fp, "学生平均分柱状图(每*代表2分)\n");
    fprintf(fp, "-----------------------------------------\n");
    for (int i = 0; i < Size; i++) {
        fprintf(fp, "%-10s: ", Arr[i].StudentName);
        // 按平均分生成对应数量的*(每2分一个*)
        int stars = (int)(Arr[i].StudentAverage / 2);
        for (int j = 0; j < stars; j++) {
            fprintf(fp, "*");
        }
        fprintf(fp, " (%.2f)\n", Arr[i].StudentAverage);
    }
    fprintf(fp, "-----------------------------------------\n");

    fclose(fp);
}

3. Write_Graph参数类型说明

你的老师要求的参数类型Student Arr[]是合理的:因为生成图表需要访问每个学生的姓名和平均分数据,直接传递整个学生数组可以让函数一次性获取所有需要的信息,无需单独传递多个参数,代码更简洁且符合面向数据的设计思路。

内容的提问来源于stack exchange,提问作者Ivandro AG

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.20 10:06:23