当前位置: 首页 > news >正文

数据结构课程设计---学生成绩管理系统

要求 

1.使用单链表实现

2.建立学生信息链表并保存到文件中

3.按照总成绩进行排序

4.打印需要补考的学生的信息

5.合并两个成绩单到一个新的成绩单中

6.查找学生成绩(按照学号)

7.打印学生成绩单

C语言代码 

#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
#include<malloc.h>
#include<stdlib.h>
#include<string.h>
struct student1//学生信息结构体
{
	char name[10];//姓名
	int  num;//学号
	int  grade[4];//语文 数学 英语
};
struct student2//单链表节点定义
{
	struct student1 data;//单链表数据域,用于存储学生信息。
	struct student2 *next;//指针域
};
/* struct student3
{
char name[10];//姓名
int  num;//学号
int  grade[4];//语文 数学 英语
};
struct student4//单链表节点定义
{
struct student3 data1;//单链表数据域,用于存储学生信息。
struct student3 data2;//指针域
};*/
struct student2 *creat(struct student2 *head)//建立单链表,输入学生信息
{
	struct student2 *p1, *p2;
	int a = 0, b = 1, c;
	char str1[15] = { "studenta.txt" };
	char str2[15] = { "studentb.txt" };
	char ch = ' ';
	FILE *fp;
	p1 = p2 = (struct student2*)malloc(sizeof(struct student2));//申请空间
	while (a <= 0)
	{
		printf("请输入您要输入的学生人数:");
		scanf("%d", &a);
		if (a <= 0)
			printf("输入有误,请重新输入!\n");
	}
	printf("1.studenta.txt文件\n2.studentb.txt\n");
	printf("请选择您要保存的文件:");
	scanf("%d", &c);
	{
		if (c == 1)
			fp = fopen(str1, "w+");
		else if (c == 2)
			fp = fopen(str2, "w+");
	}
	printf("请输入第%d学生的姓名:", b);
	scanf("%s", &(p1->data.name));
	fputs((p1->data.name), fp);//将字符串读入文件
	fputc(ch, fp);//向文件写入一个空格字符
	printf("请输入第%d个学生的学号:", b);
	scanf("%d", &(p1->data.num));
	fprintf(fp, "%d", (p1->data.num));
	fputc(ch, fp);
	printf("请输入第%d学生的语文成绩:", b);
	scanf("%d", &(p1->data.grade[0]));
	fprintf(fp, "%d", (p1->data.grade[0]));
	fputc(ch, fp);
	printf("请输入第%d学生的数学成绩:", b);
	scanf("%d", &(p1->data.grade[1]));
	fprintf(fp, "%d", (p1->data.grade[1]));
	fputc(ch, fp);
	printf("请输入第%d学生的英语成绩:", b);
	scanf("%d", &(p1->data.grade[2]));
	fprintf(fp, "%d", (p1->data.grade[2]));
	fputc(ch, fp);
	(p1->data.grade[3]) = ((p1->data.grade[0]) + (p1->data.grade[1]) + (p1->data.grade[2]));
	fprintf(fp, "%d", (p1->data.grade[3]));
	fprintf(fp, "\n");
	printf("%s的总成绩为:%d\n", (p1->data.name), (p1->data.grade[3]));
	b++;
	p1->next = NULL;
	while (b <= (a + 1))
	{
		if (head == NULL)
			head = p1;/*空表,接入表头*/
		else
			p2->next = p1;/*非空表,接到表尾*/
		p2 = p1;
		if (b != a + 1)
		{
			p1 = (struct student2*)malloc(sizeof(struct student2));
			printf("请输入第%d学生的姓名:", b);
			scanf("%s", &(p1->data.name));
			fputs((p1->data.name), fp);//将字符串读入文件
			fputc(ch, fp);//向文件写入一个空格
			printf("请输入第%d个学生的学号:", b);
			scanf("%d", &(p1->data.num));
			fprintf(fp, "%d", (p1->data.num));
			fputc(ch, fp);
			printf("请输入第%d学生的语文成绩:", b);
			scanf("%d", &(p1->data.grade[0]));
			fprintf(fp, "%d", (p1->data.grade[0]));
			fputc(ch, fp);
			printf("请输入第%d学生的数学成绩:", b);
			scanf("%d", &(p1->data.grade[1]));
			fprintf(fp, "%d", (p1->data.grade[1]));
			fputc(ch, fp);
			printf("请输入第%d学生的英语成绩:", b);
			scanf("%d", &(p1->data.grade[2]));
			fprintf(fp, "%d", (p1->data.grade[2]));
			fputc(ch, fp);
			(p1->data.grade[3]) = ((p1->data.grade[0]) + (p1->data.grade[1]) + (p1->data.grade[2]));
			fprintf(fp, "%d", (p1->data.grade[3]));
			fprintf(fp, "\n");
			printf("%s的总成绩为:%d\n", (p1->data.name), (p1->data.grade[3]));
			p1->next = NULL;
			b++;
		}
		else break;
	}
	fclose(fp);
	return head;
}

void printLinkList(struct student2 *head)//输出学生信息
{
	struct student2 *temp;
	temp = head;//取得链表的头指针
	printf("姓名      学号  语文 数学 英语 总分\n");
	while (temp != NULL)//只要是非空表
	{
		printf("%s          %d       %d          %d       %d        %d      \n", (temp->data.name), (temp->data.num), (temp->data.grade[0]), (temp->data.grade[1]), (temp->data.grade[2]), (temp->data.grade[3]));//输出链表节点的值
		temp = temp->next;///跟踪链表增长
	}
}

void find(struct student2 *head)
{
	int b;
	struct student2 *p;
	printf("请输入您要查找的学生的学号:");
	scanf("%d", &b);
	p = head;
	while (p != NULL)
	{
		if (b == p->data.num)
		{
			printf("%s           %d       %d          %d       %d        %d      \n", (p->data.name), (p->data.num), (p->data.grade[0]), (p->data.grade[1]), (p->data.grade[2]), (p->data.grade[3]));//输出链表节点的值
			break;
		}
		else
			p = p->next;
	}
}


void display(struct student2 *head)
{
	struct student2 *temp;
	FILE *fp;
	char ch = ' ';
	fp = fopen("student4.txt", "w+");
	temp = head;//取得链表的头指针
	printf("姓名      学号  语文 数学 英语 总分\n");
	while (temp != NULL)//只要是非空表
	{
		if (((temp->data.grade[0])<60) || ((temp->data.grade[1])<60) || ((temp->data.grade[2])<60))
		{
			printf("%s           %d       %d          %d       %d        %d      \n", (temp->data.name), (temp->data.num), (temp->data.grade[0]), (temp->data.grade[1]), (temp->data.grade[2]), (temp->data.grade[3]));//输出链表节点的值
			fputs((temp->data.name), fp);//将字符串读入文件
			fputc(ch, fp);//向文件写入一个空格

			fprintf(fp, "%d", (temp->data.num));
			fputc(ch, fp);
			fprintf(fp, "%d", (temp->data.grade[0]));
			fputc(ch, fp);
			fprintf(fp, "%d", (temp->data.grade[1]));
			fputc(ch, fp);
			fprintf(fp, "%d", (temp->data.grade[2]));
			fputc(ch, fp);
			fprintf(fp, "%d", (temp->data.grade[3]));
			fputc(ch, fp);

		}
		temp = temp->next;
	}
	fclose(fp);
}

void merge(struct student2 *head)
{
	char a, b;
	FILE *fpA = fopen("studenta.txt ", "r "); //A文件
	FILE *fpB = fopen("studentb.txt ", "r "); //B文件,两个作为输入文件,内容有序
	FILE *fpout = fopen("studnetc.txt ", "w "); //输出文件,三个文件都在当前目录下
	a = fgetc(fpA);
	b = fgetc(fpB);
	while (a != EOF && b != EOF) //循环读取并根据比较结果写文件,之后读取新的数据
	{
		if (a <b) //假设是升序,如果是降序使用 > 即可
		{
			fputc(a, fpout);
			a = fgetc(fpA);
		}
		else
		{
			fputc(b, fpout);
			b = fgetc(fpB);
		}
	}
	while (a != EOF) //继续读取没有操作的数据
	{
		fputc(a, fpout);
		a = fgetc(fpA);
	}
	while (b != EOF)
	{
		fputc(b, fpout);
		b = fgetc(fpB);
	}
	fclose(fpA);
	fclose(fpB);
	fclose(fpout);
	printf("合并成功,请在studentc文件中查看!\n");
}
void sort(struct student2 *head)
{
	struct student2 *newNode = (struct student2*)malloc(sizeof(struct student2));
	newNode->next = NULL;
	while (head)
	{
		struct student2 *current = head;
		struct student2 *pre = head;
		struct student2 *preMin = head;
		struct student2 *min = head;
		while (current)
		{
			if (current->data.grade[3] < min->data.grade[3])
			{
				preMin = pre;
				min = current;
			}
			pre = current;
			current = current->next;
		}
		if (min == head)
		{
			head = head->next;
			min->next = newNode->next;
			newNode->next = min;
		}
		else
		{
			preMin->next = min->next;
			min->next = newNode->next;
			newNode->next = min;
		}
	}
	head = newNode->next;
	free(newNode);
	newNode = head;
	while (newNode)
	{
		printf("%s %d %d %d %d %d\n",newNode->data.name,newNode->data.num,newNode->data.grade[0],newNode->data.grade[1],newNode->data.grade[2],newNode->data.grade[3]);
		newNode = newNode->next;
	}
	
}

void main()
{
	int i = 0;
	struct student2 *head = NULL;
	struct student2 *creat();
	void printLinkList();
	printf(" -------------------------------------------------\n");
	printf("|   ***欢迎使用西安工程大学学生成绩管理系统***    |\n");
	printf("|                                                 |\n");
	printf("|       1.建立学生成绩单                          |\n");
	printf("|       2.显示学生成绩单                          |\n");
	printf("|       3.查找学生成绩                            |\n");
	printf("|       4.按总成绩进行排序并显示                  |\n");
	printf("|       5.显示需要补考的学生信息并存入新文件4     |\n");
	printf("|       6.合并学生成绩单1和2存入新的成绩单3中     |\n");
	printf("|       7.退出系统                                |\n");
	printf("|                                                 |\n");
	printf(" -------------------------------------------------\n");
	while (i != 6)
	{
		printf("请选择您需要的操作:");
		scanf("%d", &i);
		if (i <= 0 || i>6)
			printf("输入有误,请重新输入!\n");
		else if (i == 1)
		{
			head = NULL;
			head = creat(head);
		}
		else if (i == 2)
			printLinkList(head);
		else if (i == 3)
			find(head);
		else if (i == 4)
			sort(head);
		else if (i == 5)
			display(head);
		else if (i == 6)
			merge(head);
		else
			printf("退出系统成功!!!\n");
	}
}

 

相关文章:

  • leetcode---环形链表(快慢指针证明)
  • leetcode---环形链表II
  • 剑指offer---复制带随机值的链表
  • Linux---进程概念
  • 数据结构---顺序表和链表
  • C语言课程设计---诗歌管理系统
  • 数据结构---栈和队列(栈、队列、循环队列)
  • leetcode---用两个栈实现队列
  • leetcode---用队列实现栈
  • 数据结构---堆的构建和堆排序(向下、向上调整算法)
  • Linux---进程间通信
  • LeetCode---交换链表中的节点
  • leetcode---数组中重复的数字(非常牛逼的置换算法)、原地置换算法排序
  • 数据结构---二叉树(树和二叉树的基本概念、堆的概念和堆的实现、堆排序、二叉树的顺序和链式结构及其实现、相关面试题解析)
  • leetcode---单值二叉树(递归遍历二叉树)
  • [译] React v16.8: 含有Hooks的版本
  • CAP 一致性协议及应用解析
  • ECS应用管理最佳实践
  • java中具有继承关系的类及其对象初始化顺序
  • laravel with 查询列表限制条数
  • MySQL-事务管理(基础)
  • PHP变量
  • uni-app项目数字滚动
  • 案例分享〡三拾众筹持续交付开发流程支撑创新业务
  • 将 Measurements 和 Units 应用到物理学
  • 如何合理的规划jvm性能调优
  • 一些基于React、Vue、Node.js、MongoDB技术栈的实践项目
  • 原生js练习题---第五课
  • - 转 Ext2.0 form使用实例
  • ​一些不规范的GTID使用场景
  • #if和#ifdef区别
  • ${factoryList }后面有空格不影响
  • (poj1.3.2)1791(构造法模拟)
  • (编程语言界的丐帮 C#).NET MD5 HASH 哈希 加密 与JAVA 互通
  • (过滤器)Filter和(监听器)listener
  • (入门自用)--C++--抽象类--多态原理--虚表--1020
  • (图)IntelliTrace Tools 跟踪云端程序
  • (一)kafka实战——kafka源码编译启动
  • (原創) X61用戶,小心你的上蓋!! (NB) (ThinkPad) (X61)
  • (转)scrum常见工具列表
  • (转)socket Aio demo
  • (转)利用ant在Mac 下自动化打包签名Android程序
  • (转载)PyTorch代码规范最佳实践和样式指南
  • *Django中的Ajax 纯js的书写样式1
  • . Flume面试题
  • ./和../以及/和~之间的区别
  • .bat批处理(八):各种形式的变量%0、%i、%%i、var、%var%、!var!的含义和区别
  • .mat 文件的加载与创建 矩阵变图像? ∈ Matlab 使用笔记
  • .NET CF命令行调试器MDbg入门(四) Attaching to Processes
  • .NET delegate 委托 、 Event 事件,接口回调
  • .NET Standard 的管理策略
  • .Net6支持的操作系统版本(.net8已来,你还在用.netframework4.5吗)
  • .NET开发人员必知的八个网站
  • .net中我喜欢的两种验证码
  • .pub是什么文件_Rust 模块和文件 - 「译」