学生成绩记录簿管理---课程设计(C语言简易版)

 

编制一个C语言成绩记录簿,每个学生信息包括:学号、姓名、C语言成绩。具体功能:

1)创建一个文本文件用来记录学生信息,输入至少30名学生的信息,保存在文本文件中;

2)将文本文件中的数据读出,按学号或姓名查询成绩;

3)能添加成绩记录;

4)能修改指定姓名或学号的学生的成绩;

5)显示输出60分以下、60~79、80~89、90分以上各分数段的学生信息,显示及格率和平均分,显示最高分和最低分,显示所有学生的排名(不能改变学生的学号顺序);

6)以上信息能保存在原文本文件中。

简易流程图: 

 

 

源码: 

#define _CRT_SECURE_NO_WARNINGS  1
#include <stdio.h>
#include <string.h>
#include <math.h>
#include "malloc.h"
#include <stdlib.h>

#define   STU_NUM 100                       //学生人数(可一键修改)
#define   LEN sizeof(struct Student)        //链表长度

typedef struct Student{             //定义类并取一个别名
	long num;	                    //每个学生的学号
	char name[20];            	    //每个学生的姓名
	float score;	                //每个学生的C语言成绩
	struct Student* next;
}STU;

int Menu();                                    //创建菜单
void Print(STU* head, int n);                  //打印函数
void AverSumofCourse(STU* head, int n);        //计算每个学生的总分和平均分
STU* SortbyScore(STU* head, int n);			   //按每个学生的总分由高到低排出名次表
STU* Creat(int n);							   //创建链表并录入信息
STU* Creat1(int n);							   //功能同上
STU* SortbyNum(STU* head);                     //按学号由小到大排出成绩表
STU* SortbyName(STU* head, int n);             //按姓名的字典顺序排出成绩表
void SearchbyNum(STU* head, int n);            //按学号查询学生排名及其考试成绩
void SearchbyName(STU* head, int n);           //按姓名查询学生排名及其考试成绩
void ModifybyNum(STU* head, int n);            //按学号查询并修改学生考试成绩
void ModifybyName(STU* head, int n);		   //按姓名查询并修改学生考试成绩
void StatisticAnalysis(STU* head, int n);      //按类别及比例输出
void WritetoFile(STU* head, int n);            //将每个学生的纪录信息写入文件
STU* ReadfromFile(STU* head, int* n);          //从文件中读出每个学生的纪录信息并显示

int main(){
	int n, i;
	STU* head;              //定义链表头指针
	head = (STU*)malloc(LEN);
	head = ReadfromFile(head, &n);
	while (1){
		i = Menu();
		if (i == 1) {
			printf("******************************************************************************\n");
			printf("请输入您要录入的学生人数:\n");    //输入录入学生人数
			scanf("%d", &n);
			printf("请依次输入录入学生的学号、姓名和C语言成绩(每输入一个数据按回车键)\n");
			head = Creat(n);
			//system("cls");  //清屏
		}
		else if (i == 2) {
			printf("******************************************************************************\n");
			printf("*                                                                            *\n");
			printf("*                <1.按学号查询>           <2.按姓名查询>                     *\n");
			printf("*                                                                            *\n");
			printf("******************************************************************************\n");
			printf("请选择您的查询方式:");
			int choice;
			scanf("%d", &choice);
			if (choice == 1) {
				printf("\n");
				printf("******************************************************************************\n");
				printf("请输入您要查询学生的学号:");
				SearchbyNum(head, n);
			}
			else {
				printf("\n");
				printf("******************************************************************************\n");
				printf("请输入您要查询学生的姓名:");
				SearchbyName(head, n);
			}
		}
		else if (i == 3) {
			printf("******************************************************************************\n");
			printf("*                                                                            *\n");
			printf("*                <1.按学号查询>           <2.按姓名查询>                     *\n");
			printf("*                                                                            *\n");
			printf("******************************************************************************\n");
			printf("请选择您的查询方式:");
			int choice;
			scanf("%d", &choice);
			if (choice == 1) {
				printf("\n");
				printf("******************************************************************************\n");
				printf("请输入您要查询学生的学号:");
				ModifybyNum(head, n);
			}
			else {
				printf("\n");
				printf("******************************************************************************\n");
				printf("请输入您要查询学生的姓名:");
				ModifybyName(head, n);
			}
		}
		else if (i == 4) {
			printf("******************************************************************************\n");
			printf("*                                                                            *\n");
			printf("*        <1.按学号排序>        <2.按姓名排序>        <3.按成绩排序>          *\n");
			printf("*                                                                            *\n");
			printf("******************************************************************************\n");
			printf("请选择您的查询方式:");
			int style;
			scanf("%d", &style);
			if (style == 1) {
				printf("正在根据学生学号排序:\n");
				head = SortbyNum(head);
				Print(head, n);
			}
			else if (style == 2) {
				printf("正在根据学生姓名排序:\n");
				head = SortbyName(head, n);
				Print(head, n);
			}
			else if (style == 3) {
				printf("正在根据学生C语言成绩排序:\n");
				head = SortbyScore(head, n);
				Print(head, n);
			};
		}
		else if (i == 5) {
			printf("******************************************************************************\n");
			StatisticAnalysis(head, n);
			AverSumofCourse(head, n);
		}
		else if (i == 0) {
			printf("******************************************************************************\n");
			printf("                      欢迎下次使用本系统,谢谢!!!\n");
			printf("******************************************************************************\n");
			break;
		}
		else {
			printf("******************************************************************************\n");
			printf("                        输入错误!!!请重新输入。\n");
			printf("******************************************************************************\n");
		}
	}
	WritetoFile(head, n);
	return 0;
}
// 创建菜单
int Menu(){
	int i;
	system("title 学生成绩记录簿管理");
	printf("\n\n");
	printf("******************************************************************************\n");
	printf("*                                                                            *\n");
	printf("*                <1.录入学生成绩>          <2.查询学生成绩>                  *\n");
	printf("*                <3.修改学生成绩>          <4.排序学生成绩>                  *\n");
	printf("*                <5.按分段分析成绩>        <0.退出成绩管理系统>              *\n");
	printf("*                                                                            *\n");
	printf("******************************************************************************\n");
	printf("\n");
	printf("\n");
	printf("#请输入您的操作:");
	scanf("%d", &i);
	return i;
}

// 创建链表
STU* Creat(int n) {
	STU* head = NULL;
	STU* p1, * p2 = NULL;
	int i;
	// system("cls");
	for (i = 1; i < n + 1; i++){
		p1 = (STU*)malloc(LEN);
		printf("学号:");
		scanf("%ld", &p1->num);
		printf("姓名:");
		scanf("%s", p1->name);
		printf("C语言成绩:");
		scanf("%f", &p1->score);
		p1->next = NULL;
		if (i == 1){
			head = p2 = p1;
		}
		else{
			p2->next = p1;
			p2 = p1;
		}
	}
	return(head);
}
STU* Creat1(int n){
	STU* head = NULL;
	STU* p1, * p2 = NULL;
	int i;
	// system("cls");
	for (i = 1; i < n + 1; i++){
		p1 = (STU*)malloc(LEN);
		p1->next = NULL;
		if (i == 1){
			head = p2 = p1;
		}
		else{
			p2->next = p1;
			p2 = p1;
		}
	}
	return(head);
}


void SearchbyNum(STU* head, int n){
	long num;
	int flag = 1;
	scanf("%ld", &num);
	STU* p;
	p = head;
	if (head != NULL){
		do {
			if (p->num == num){
				printf("%ld\t%s\t", p->num, p->name);
				printf("%.0f\t", p->score);
				printf("\n");
				flag = 0;
			}
			p = p->next;
		} while (p != NULL);
		if (flag){
			printf("抱歉,没有找到该学生的成绩,请确定其是否已录入系统。\n");
		}
	}
	printf("******************************************************************************\n");
}
void SearchbyName(STU* head, int n){
	char name[20];
	int flag = 1;
	scanf("%s", name);
	STU* p;
	p = head;
	if (head != NULL){
		do {
			if (strcmp(name, p->name) == 0){
				printf("%ld\t%s\t", p->num, p->name);
				printf("%.0f\t", p->score);
				printf("\n");
				flag = 0;
			}
			p = p->next;
		} while (p != NULL);
		if (flag){
			printf("抱歉,没有找到该学生的成绩,请确定其是否已录入系统。\n");
		}
	}
	printf("******************************************************************************\n");
}


void ModifybyNum(STU* head, int n) {
	long num;
	int flag = 1;
	scanf("%ld", &num);
	STU* p;
	p = head;
	if (head != NULL) {
		do {
			if (p->num == num) {
				printf("请输入该学生的新成绩:");
				scanf("%f", &(p->score));
				printf("\n");
				printf("修改成功!!!\n");
				flag = 0;
			}
			p = p->next;
		} while (p != NULL);
		if (flag) {
			printf("抱歉,没有找到该学生的成绩,请确定其是否已录入系统。\n");
		}
	}
	printf("******************************************************************************\n");
}
void ModifybyName(STU* head, int n) {
	char name[20];
	int flag = 1;
	scanf("%s", name);
	STU* p;
	p = head;
	if (head != NULL) {
		do {
			if (strcmp(name, p->name) == 0) {
				printf("请输入该学生的新成绩:");
				scanf("%f", &(p->score));
				printf("\n");
				printf("修改成功!!!\n");
				flag = 0;
			}
			p = p->next;
		} while (p != NULL);
		if (flag) {
			printf("抱歉,没有找到该学生的成绩,请确定其是否已录入系统。\n");
		}
	}
	printf("******************************************************************************\n");
}


STU* SortbyNum(STU* head){
	STU* first;    //为原链表剩下用于直接插入排序的节点头指针
	STU* t;        //临时指针变量:插入节点
	STU* p=NULL, * q;     //临时指针变量
	first = head->next;      //原链表剩下用于直接插入排序的节点链表:可根据图12来理解
	head->next = NULL;       //只含有一个节点的链表的有序链表:可根据图11来理解
	while (first != NULL){        //遍历剩下无序的链表
		//注意:这里for语句就是体现直接插入排序思想的地方
		for (t = first, q = head; ((q != NULL) && (q->num < t->num)); p = q, q = q->next);  //无序节点在有序链表中找插入的位置
		first = first->next; //无序链表中的节点离开,以便它插入到有序链表中
		if (q == head){      //插在第一个节点之前
			head = t;
		}
		else{           //p是q的前驱
			p->next = t;
		}
		t->next = q;     //完成插入动作
		//first = first->next;
	}
	return head;
}
STU* SortbyName(STU* head, int n){
	STU* endpt;    //控制循环比较
	STU* p;        //临时指针变量
	STU* p1, * p2;
	p1 = (STU*)malloc(LEN);
	p1->next = head;        //注意理解:我们增加一个节点,放在第一个节点的前面,主要是为了便于比较。因为第一个节点没有前驱,我们不能交换地址
	head = p1;                 //让head指向p1节点,排序完成后,我们再把p1节点释放掉
	for (endpt = NULL; endpt != head; endpt = p){
		for (p = p1 = head; p1->next->next != endpt; p1 = p1->next){
			if (strcmp(p1->next->name, p1->next->next->name) > 0){  //如果前面的节点键值比后面节点的键值大,则交换
				p2 = p1->next->next;
				p1->next->next = p2->next;
				p2->next = p1->next;
				p1->next = p2;     //结合第4点理解
				p = p1->next->next;   //结合第6点理解
			}
		}
	}
	p1 = head;              //把p1的信息去掉
	head = head->next;       //让head指向排序后的第一个节点
	free(p1);          //释放p1
	p1 = NULL;          //p1置为NULL,保证不产生“野指针”,即地址不确定的指针变量
	return head;
}
STU* SortbyScore(STU* head, int n){
	STU* endpt;    //控制循环比较
	STU* p;        //临时指针变量
	STU* p1, * p2;
	p1 = (STU*)malloc(LEN);
	p1->next = head;           //注意理解:我们增加一个节点,放在第一个节点的前面,主要是为了便于比较。因为第一个节点没有前驱,我们不能交换地址
	head = p1;                 //让head指向p1节点,排序完成后,我们再把p1节点释放掉
	for (endpt = NULL; endpt != head; endpt = p){
		for (p = p1 = head; p1->next->next != endpt; p1 = p1->next){
			if (p1->next->score < p1->next->next->score){  //如果前面的节点键值比后面节点的键值大,则交换
				p2 = p1->next->next;
				p1->next->next = p2->next;
				p2->next = p1->next;
				p1->next = p2;
				p = p1->next->next;
			}
		}
	}
	p1 = head;              //把p1的信息去掉
	head = head->next;       //让head指向排序后的第一个节点
	free(p1);          //释放p1
	p1 = NULL;          //p1置为NULL,保证不产生“野指针”,即地址不确定的指针变量
	return head;
}


void AverSumofCourse(STU* head, int n){
	STU* p;
	p = head;
	float sum = 0;
	if (head != NULL) {        //只要不是空链表,就输出链表中所有节点
		do {
			sum += p->score;
			p = p->next;     //移到下一个节点
		} while (p != NULL);
		printf("学生平均分为:");
		printf("%.2f\n", sum / n);
		printf("******************************************************************************\n");
	}
}

void StatisticAnalysis(STU* head, int n) {
	int a[6];
	STU* p;
	p = head;
	int  j;
	p = head;                  // 初始化
	for (j = 0; j < 6; j++) {  // 初始化
		a[j] = 0;
	}
	do {
		if (p->score < 60) {
			a[0]++;
		}
		else if (p->score < 70) {
			a[1]++;
		}
		else if (p->score < 80) {
			a[2]++;
		}
		else if (p->score < 90) {
			a[3]++;
		}
		else if (p->score < 100) {
			a[4]++;
		}
		else {
			a[5]++;
		}
		p = p->next;
	} while (p != NULL);
	printf("******************************************************************************\n");
	printf("* 成绩情况如下:\n");
	char x = '%';
	printf("* <60\t%d\t%.2lf", a[0], (100 * (float)a[0] / n)); printf("%c", x); printf("\n");
	printf("* %d-%d\t%d\t%.2lf", 60, 69, a[1], 100 * (float)a[1] / n);  printf("%c",x); printf("\n");
	printf("* %d-%d\t%d\t%.2lf", 70, 79, a[2], 100 * (float)a[2] / n);  printf("%c", x); printf("\n");
	printf("* %d-%d\t%d\t%.2lf", 80, 89, a[3], 100 * (float)a[3] / n);  printf("%c", x); printf("\n");
	printf("* %d-%d\t%d\t%.2lf", 90, 99, a[4], 100 * (float)a[4] / n);  printf("%c", x); printf("\n");
	printf("* %d\t%d\t%.2lf", 100, a[5], 100 * (float)a[5] / 6.0);  printf("%c", x); printf("\n");
	printf("学生及格率:%.2lf", 100*(float)(n - a[0]) / n);  printf("%c", x);
	printf("\n");
}


void Print(STU* head, int n){
	STU* p;
	p = head;
	if (head != NULL){        //只要不是空链表,就输出链表中所有节点
		printf("******************************************************************************\n");
		do{
			printf("%ld\t%s\t", p->num, p->name);
			printf("%.0f\t", p->score);
			printf("\n");
			p = p->next;     //移到下一个节点
		} while (p != NULL);
		printf("******************************************************************************\n");
	}
}

STU* ReadfromFile(STU* head, int* n){
	STU* p;
	FILE* fp;
	int i;
	if ((fp = fopen("student.txt", "r")) == NULL){
		printf("打开文件失败!!!\n");
		return NULL;
	}
	fscanf(fp, "%d\n", n);
	head = Creat1(*n);  //创建了一个空链表,并且赋给head
	p = head;
	for (i = 0; i < *n; i++){
		fscanf(fp, "%12ld", &p->num);
		fscanf(fp, "%12s", &p->name);
		fscanf(fp, "%12f", &p->score);
		p = p->next;
	}
	i = *n;
	//printf("文件读取成功!!!\n");
	fclose(fp);
	//Print(head, i);
	return head;
}
void WritetoFile(STU* head, int n){
	STU* p;
	p = head;
	FILE* fp;
	int i;
	printf("******************************************************************************\n");
	if ((fp = fopen("student.txt", "a+")) == NULL){
		printf("打开文件失败!!!\n");
		return;
	}
	for (i = 0; i < n; i++){
		fprintf(fp, "\n");
		fprintf(fp, "%12ld%12s", p->num, p->name);
		fprintf(fp, "%12.0f", p->score);
		p = p->next;
	}
	printf("******************************************************************************\n");
	printf("                             保存数据成功!!!\n");
	printf("******************************************************************************\n");
	fclose(fp);
}

 

总结: 

        本课程设计为C语言程序设计,使用了链表进行数据存储,设计相对简洁且已经过调试。 

  • 7
    点赞
  • 19
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 3
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

想我记得写信

您的鼓励是我创作最大的动力!

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值