广工课程设计——学生成绩统计系统
来源:互联网 发布:淘宝店铺海报尺寸多少 编辑:程序博客网 时间:2024/04/30 19:38
【前言:如题,本文中涉及的项目是去年应学妹要求帮忙写的,纯C语言,在Turbo C下编译通过。最近整理资料,觉得该项目中涉及到的结构体、链表、文件操作、断言等基础知识,以及这个小项目的函数设计和变量命名等容易忽略的知识对初学C语言的朋友应该会有帮助,所以决定发布出来。同时,给需要完成类似课程设计的学生一个参考,但是应注意理解其中的知识点,而不应复制粘贴草草了事。】
问题描述:
学期考试结束,统计某班每个学生的平均成绩,每门课的平均成绩,并按个人平均成绩从高到低的顺序输出成绩,输出不及格人名单。输入、输出格式自定。
实现提示:
考试课程有:高等数学、物理、外语、C语言4门课程。录入所有同学的成绩,对数据进行处理,输出所要求的内容,程序的功能主要包括以下几个方面:
① 输入成绩
② 修改记录
③ 删除记录
④ 输出成绩并按平均成绩排序,并标记平均分不及格的学生。
⑤ 界面提供上述功能选择。
⑥ 学生人数由软件根据输入的成绩记录数自动控制。
⑦ 提供输出成绩到文件以及从文件读取成绩功能。
测试数据:(自定模拟数据如下)
整体设计
通过问题描述和对软件功能需求的分析,我们对程序的设计作出整体构思,其关键点在于数据结构的设计以及对数据的保存。本文提出一种用线性表和文件IO实现上述需求的解决方法,具体设计如下所述。
数据结构
本文将线性表设计双向循环链表,其中结点数据域为结构体stInfo。
/// 用户信息typedef struct student{ int id; // 学号 char name[NAMELEN]; // 姓名 int AMaths; // 高数成绩 int Physics; // 物理成绩 int Foreign; // 外语成绩 int Clan; // C语言成绩 float GPA; // 平均分}stInfo;
/// 用户信息结点结构体typedef struct studentNode{ stInfo data; //<! 数据域 struct studentNode *prev; //<! 指针域 struct studentNode *next;}stNode;
算法
程序多处需要多链表进行查询和排序,为方便起见,本文使用遍历算法进行查询,使用冒泡法进行排序。详见附录。
文件操作
包括文件内容的读取和写入。为方便用户直接在文件中添加学生信息、查看程序对数据处理后的结果以及便于演示,我们并没有以二进制方式操作数据,而是将数据以文本方式写入文件,因此增加了对字符串操作的代码。详见附录。
程序流程图
部分操作及细节说明
1、该系统提供五个选项,根据提示操作即可。
2、文件操作涉及的两个文件,宏定义如下
// 保存学生各科成绩#define STUDENTS_FILE "./students.txt"// 保存成绩处理完成后的结果#define SCORE_FILE "./GPA.txt"
正常情况下,数据从文件STUDENTS_FILE和手动输入两种渠道进入链表,经过处理后再由链表流向文件STUDENTS_FILE和文件SCORE_FILE。
3、主程序负责接收用户输入的数据,并传到相应接口函数,由于标准输入(即键盘)是带缓冲的,因此需要添加下面这行代码,用以清空缓冲区。
while(getchar() != '\n') {;}
4、输入ID号和成绩时需注意:系统将ID号范围限定为1000到1999,且不能重复,成绩范围限定为0到100。
接口函数说明
相关宏定义
#define OK 1#define ERROR 0#define EXIT 2#define EXIST 1#define NOTEXIST 0
系统操作相关函数
/* * 检查用户输入的ID是否存在于链表; * 存在返回EXIST,不存在返回NOTEXIST。 */int CheckID(stNode *stHead, int id);/* * 检查用户输入的成绩是否合理; * 无返回值。*/void InputScore(int *score);/* * 初始化系统,创建链表并从STUDENTS_FILE中读取数据插入链表; * 初始化成功返回OK,否则返回ERROR。*/int InitSystem(void);/* * 等待用户输入结点数据并插入链表; * 无返回值。*/void InputRecord(void);/* * 等待用户修改结点数据; * 无返回值。*/void AlterRecord(void);/* * 等待用户删除特定结点; * 无返回值。*/void DeleteRecord(void);/* * 按系统需求对链表进行处理,并将结果输出; * 无返回值。*/void OutputRecord(void);/* * 退出系统,保存链表数据,释放内存; * 无返回值。*/void Exit(void);
链表操作相关函数
/* * 初始化一个双循环链表,*stHead为链表头指针; * 初始化成功返回OK,否则返回ERROR。*/int InitList(stNode **stHead);/* * 显示链表stHead所包含的内容; * 无返回值。*/void ShowList(stNode *stHead);/* * 将链表stHead复制为cpHead; * 复制成功返回链表头指针,否则返回NULL。*/stNode *CopyList(stNode *cpHead, stNode *stHead);/* * 将链表stHead的数据保存到文件fp中; * 无返回值。*/void SaveList(FILE *fp, stNode *stHead);/* * 释放链表stHead所占用的内存; * 无返回值。*/void FreeList(stNode *stHead);/* * 将以st作为数据域的结点插入到链表stHead的末尾; * 插入成功返回OK,否则返回ERROR。*/int InsertNode(stNode *stHead, stInfo st);/* * 删除链表stHead上相关ID号的结点; * 删除成功返回OK,否则返回ERROR。*/int DeleteNode(stNode *stHead, int id);/* * 将链表stHead相关ID号的column字段的成绩修改为score; * 修改成功返回OK,否则返回ERROR。*/int AlterNode(stNode *stHead, int id, int column, int score);/* * 将链表stHead的结点按平均分降序来排序; * 无返回值。*/void DescSort(stNode *stHead);/* * 显示链表stHead中平均分不及格的名单; * 无返回值。*/void ShowFail(stNode *stHead);
附录
/************************************************ File name : resultsMS.c Created date : 2014-10-25 18:38 Modified date : 2014-10-27 20:07 Author : luhuadong Email : luhuadong@163.com Description : ************************************************/#include <assert.h>#include <stdio.h>#include <stdlib.h>#include <string.h>/// 保存学生各科成绩#define STUDENTS_FILE "./students.txt"/// 保存成绩处理完成后的结果#define SCORE_FILE "./GPA.txt"#define OK 1#define ERROR 0#define EXIT 2#define EXIST 1#define NOTEXIST 0/// 用户基本信息数据长度#define STINFOLEN 80/// 结构体student中成员name的长度#define NAMELEN 32/// 用户信息typedef struct student{ int id; char name[NAMELEN]; int AMaths; int Physics; int Foreign; int Clan; float GPA;}stInfo;/// 用户信息结点结构体typedef struct studentNode{ stInfo data; //<! 数据域 struct studentNode *prev; //<! 指针域 struct studentNode *next;}stNode;stNode *stHead = NULL;int status = OK;/* 函数声明 */int CheckID(stNode *stHead, int id);void InputScore(int *score);int InitSystem(void);void InputRecord(void);void AlterRecord(void);void DeleteRecord(void);void OutputRecord(void);void Exit(void);int InitList(stNode **stHead);void ShowList(stNode *stHead);stNode *CopyList(stNode *cpHead, stNode *stHead);void SaveList(FILE *fp, stNode *stHead);void FreeList(stNode *stHead);int InsertNode(stNode *stHead, stInfo st);int DeleteNode(stNode *stHead, int id);int AlterNode(stNode *stHead, int id, int column, int score);void DescSort(stNode *stHead);void ShowFail(stNode *stHead);/* ******************************************************** */int main(void){ int mode; // 模式选择 // 系统初始化 if(ERROR == InitSystem()) { perror("Initialized system fail"); return -1; } while(OK == status) { // system("clear"); printf("++++++++++++++++++++++++++++++\n"); printf(" 1-输入成绩\n 2-修改记录\n 3-删除记录\n 4-输出成绩\n 5-退出\n"); printf("++++++++++++++++++++++++++++++\n>>"); while(scanf("%d", &mode) == 0) { while(getchar() != '\n') {;} printf("error, try again >>\n"); } while(getchar() != '\n') {;} switch(mode) { case 1: InputRecord(); break; case 2: AlterRecord();break; case 3: DeleteRecord();break; case 4: OutputRecord();break; case 5: Exit(); break; default: break; } } return 0;}/* ******************************************************** */int CheckID(stNode *stHead, int id){ stNode *currNode = stHead->next; while(currNode != stHead) { if(id == currNode->data.id) {return EXIST;} currNode = currNode->next; } return NOTEXIST;}int InitSystem(void){ FILE *fp = NULL; stInfo st; int i=0, j=0, k=0; char readbuf[STINFOLEN]; //<! 存放readFromFile()读取的字符串 char strStInfo[6][NAMELEN]; //<! 保存每次读取的一条记录 if(ERROR == InitList(&stHead)) { printf("Created initial LIST failed.\n"); status = ERROR; return ERROR; } fp = fopen(STUDENTS_FILE, "r"); if(NULL == fp) { printf("Open %s failed.\n", STUDENTS_FILE); status = ERROR; return ERROR; } while(NULL != fgets(readbuf, STINFOLEN, fp)) { /// 每一条记录共有6个字段 for(i=0; i<6; i++) { while((' ' != readbuf[j]) \ && ('\n' != readbuf[j]) \ && ('\t' != readbuf[j])) { strStInfo[i][k++] = readbuf[j++]; } strStInfo[i][k] = '\0'; j++; //<! 跳过空格符 k = 0; } j = 0; st.id = atoi(strStInfo[0]); strcpy(st.name, strStInfo[1]); st.AMaths = atoi(strStInfo[2]); st.Physics = atoi(strStInfo[3]); st.Foreign = atoi(strStInfo[4]); st.Clan = atoi(strStInfo[5]); st.GPA = 0; if(ERROR == InsertNode(stHead, st)) { return ERROR;} } printf("初始化链表==>\n"); ShowList(stHead); fclose(fp); return OK;}void InputScore(int *score){ scanf("%d", score); while(getchar() != '\n') {;} while(*score < 0 || *score > 100) { printf("【成绩范围:0--100】\n>>"); scanf("%d", score); while(getchar() != '\n') {;} } return ;}void InputRecord(void){ stInfo st; printf("Input ID: "); scanf("%d", &st.id); if(st.id > 1999 || st.id < 1000) { printf("ID范围为1000~1999.\n"); } if(EXIST == CheckID(stHead, st.id)) { printf("ID重复!\n"); return ; } while(getchar() != '\n') {;} printf("姓名:"); gets(st.name); printf("高数成绩:"); InputScore(&st.AMaths); printf("物理成绩:"); InputScore(&st.Physics); printf("外语成绩:"); InputScore(&st.Foreign); printf("C语言成绩:"); InputScore(&st.Clan); if(OK == InsertNode(stHead, st)) {printf("OK\n");} else {printf("Failed\n");} return ;}void AlterRecord(void){ int id, column, score; printf("Input ID: "); scanf("%d", &id); if(NOTEXIST == CheckID(stHead, id)) { printf("ID不存在!\n"); return ; } printf("1-高数\t2-物理\t3-外语\t4-C语言\n修改科目>>"); scanf("%d", &column); printf("修改成绩为:"); scanf("%d", &score); if(OK == AlterNode(stHead, id, column, score)) {printf("OK\n");} else {printf("Failed\n");} return ;}void DeleteRecord(void){ int id; printf("Input id: "); scanf("%d", &id); if(NOTEXIST == CheckID(stHead, id)) { printf("ID不存在!\n"); return ; } if(OK == DeleteNode(stHead, id)) {printf("OK\n");} else {printf("Failed\n");} return ;}void OutputRecord(void){ FILE *fp = NULL; stNode *cpHead = NULL; if(ERROR == InitList(&cpHead)) { printf("Created output LIST failed.\n"); status = ERROR; return ; } CopyList(cpHead, stHead); if(NULL == cpHead) { printf("Copy failed.\n"); return ; } DescSort(cpHead); printf("按平均分排序==>\n"); ShowList(cpHead); fp = fopen(SCORE_FILE, "w"); if(NULL == fp) { printf("Open %s failed.\n", SCORE_FILE); return ; } printf("不及格学生==>\n"); ShowFail(cpHead); SaveList(fp, cpHead); FreeList(cpHead); fclose(fp); return ;}void Exit(void){ FILE *fp = fopen(STUDENTS_FILE, "w"); if(NULL == fp) { printf("Open %s failed.\n", STUDENTS_FILE); return ; } SaveList(fp, stHead); printf("Save to file ...\n"); FreeList(stHead); fclose(fp); printf("successful exit.\n"); status = EXIT; return ;}//****************************************************int InitList(stNode **stHead){ *stHead = (stNode *)malloc(sizeof(stNode)); if(NULL != *stHead) { (*stHead)->prev = *stHead; (*stHead)->next = *stHead; return OK; } return ERROR;}void ShowList(stNode *stHead){ stNode *currNode = NULL; assert(NULL != stHead); printf("================================================================\n"); printf("学号\t姓名\t\t高数\t物理\t外语\tC语言\t平均分\n"); currNode = stHead->next; while(currNode != stHead) { printf("%d\t%-8s\t%d\t%d\t%d\t%d\t%.2f\n", currNode->data.id, \ currNode->data.name, currNode->data.AMaths, \ currNode->data.Physics, currNode->data.Foreign, \ currNode->data.Clan, currNode->data.GPA); currNode = currNode->next; } printf("================================================================\n");}stNode *CopyList(stNode *cpHead, stNode *stHead){ stInfo st; stNode *currNode = NULL; assert(NULL != cpHead && NULL != stHead); currNode = stHead->next; while(currNode != stHead) { st = currNode->data; st.GPA = (float)(st.AMaths + st.Physics + st.Foreign + st.Clan)/4; if(ERROR == InsertNode(cpHead, st)) {return NULL;} currNode = currNode->next; } return cpHead;}void SaveList(FILE *fp, stNode *stHead){ stNode *currNode = NULL; assert(NULL != fp && NULL != stHead); currNode = stHead->next; while(currNode != stHead) { fprintf(fp, "%d %s\t%d %d %d %d %.2f\n", currNode->data.id, \ currNode->data.name, currNode->data.AMaths, \ currNode->data.Physics, currNode->data.Foreign, \ currNode->data.Clan, currNode->data.GPA); currNode = currNode->next; }}void FreeList(stNode *stHead){ /// 释放链表 stNode *currNode = stHead->next; while(currNode != stHead) { stHead->next = currNode->next; free(currNode); currNode = stHead->next;; } //free(currNode); //<! 当用户信息表为空时会导致出错 free(stHead);}int InsertNode(stNode *stHead, stInfo st){ stNode *new = NULL; assert(NULL != stHead); new = (stNode *)malloc(sizeof(stNode)); if(NULL != new) { new->data = st; new->next = stHead; new->prev = stHead->prev; stHead->prev->next = new; stHead->prev = new; return OK; } return ERROR;}int DeleteNode(stNode *stHead, int id){ stNode *currNode = stHead->next; stNode *delNode = NULL; while(currNode != stHead) { if(id == currNode->data.id) { delNode = currNode; currNode->prev->next = currNode->next; currNode->next->prev = currNode->prev; currNode = currNode->prev; free(delNode); return OK; } currNode = currNode->next; } return ERROR;}int AlterNode(stNode *stHead, int id, int column, int score){ stNode *currNode = stHead->next; stNode *delNode = NULL; while(currNode != stHead) { if(id == currNode->data.id) { printf("修改前==>\n高数:%d\t物理:%d\t外语:%d\tC语言:%d\n", \ currNode->data.AMaths, currNode->data.Physics, \ currNode->data.Foreign, currNode->data.Clan); if(1 == column) {currNode->data.AMaths = score;} else if(2 == column) {currNode->data.Physics = score;} else if(3 == column) {currNode->data.Foreign = score;} else if(4 == column) {currNode->data.Clan = score;} else {return ERROR;} printf("修改后==>\n高数:%d\t物理:%d\t外语:%d\tC语言:%d\n", \ currNode->data.AMaths, currNode->data.Physics, \ currNode->data.Foreign, currNode->data.Clan); return OK; } currNode = currNode->next; } return ERROR;}void DescSort(stNode *stHead){ stInfo tmp; stNode *curr1 = stHead->next; stNode *curr2 = stHead->next; stNode *lastNode = stHead->prev; for(curr1 = stHead->next; curr1 != stHead->prev; curr1 = curr1->next, lastNode = lastNode->prev) { for(curr2 = stHead->next; curr2 != lastNode; curr2 = curr2->next) { if(curr2->data.GPA < curr2->next->data.GPA) { tmp = curr2->data; curr2->data = curr2->next->data; curr2->next->data = tmp; } } }}void ShowFail(stNode *stHead){ stNode *currNode = NULL; assert(NULL != stHead); printf("********************************\n"); printf("* 学号\t姓名\t\t平均分\n"); currNode = stHead->prev; while(currNode->data.GPA < 60) { printf("* %d\t%-8s\t%.2f\n", currNode->data.id, \ currNode->data.name, currNode->data.GPA); currNode = currNode->prev; } printf("********************************\n");}
- 广工课程设计——学生成绩统计系统
- 期末课程设计—学生成绩查询系统
- 课程设计-学生成绩系统
- 数据结构课程设计——学生成绩管理
- 广工嵌入式系统课程设计——单片机售票机
- 学生成绩统计管理系统
- 第二周——学生成绩统计
- 结构体——学生成绩统计
- 课程设计-学生成绩管理
- 课程设计--学生成绩管理
- 课程设计 学生成绩查询
- 课程设计——学生信息管理系统
- 数据结构课程设计——学生信息管理系统
- 课程设计——学生信息管理系统
- 数据结构课程设计——学生信息管理系统
- 数据结构课程设计——学生信息管理系统
- 数据结构课程设计——学生信息管理系统
- 数据结构课程设计—学生信息管理系统
- iOS开发小牛的第一篇日志
- php数组遍历
- WordCount背后的数据流
- 浅谈QFile
- apache的一些版本网址
- 广工课程设计——学生成绩统计系统
- 应该如何在小,中,大型应用开发中组织前端js代码?
- HDFS介绍及结构和shell操作
- 进程间通信
- BZOJ1033 杀蚂蚁
- PHP如何判断一个gif图片是否为动画?
- 《JavaScript语言精粹》读书笔记
- centos6.5 hadoop2.6.3分布式集群安装
- 英国皇家邮政申请退款及自助兑换一张英国支票