基于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
相关产品推荐
相关产品推荐

