链表实现学生信息管理系统--数据结构(C语言)

**题目说明**

每个学生的信息包括:学号、姓名、性别、手机号码、数学分数、语文分数。程序使用链表结构完成以下管理功能:

  1. 创建链表
  2. 从键盘输入某个学生的信息,并将其插入链表中
  3. 从键盘输入某个学生的学号,并将其从链表中删除
  4. 对某个学生的信息的修改
  5. 查询符合某个条件(允许条件与或非组合)的学生,并打印查询结果
  6. 对学生按照某个信息进行排序并输出

扩展功能:
7. 支持从Excel表格导入学生数据
8. 支持将链表中的内容导出到Excel表格
9. 对人数、性别、分数支持简单的统计功能,如总体人数,男女比例,各区间分数百分比计算等

这里笔者指出当初在写之前搜索到的同题项目的大佬解答,留下链接: https://blog.csdn.net/weixin_42422341/article/details/86777562

放源代码前指出本项目要注意的几点:
1.文件!!导入导出的Excel文件都在了桌面,记得修改路径!
2.数据的输入的格式要求最好提前设置(在导入的Excel文件中笔者设置了电话号码的长度为11位,姓名长度为2位)
3.在项目验收时可能会要求判断输入错误的数据类型时的情况,读者可以自己自行添加代码完成需求
*4.数据的导入有两种方式,主界面输入“1”可进行手动输入,或者输入“9”直接导入已保存的数据,导出的文件为空文件,导入的文件如下(可自行添加/设置)

tips:喜欢还不赞,年轻人你要耗子尾汁,好好饭思!
链表实现学生信息管理系统--数据结构(C语言)_第1张图片源代码:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>  
#define OK 1
#define ERROR 0
#define TRUE 1
#define FALSE 0
#define MAXSIZE 20

typedef int Status;                       /* Status是函数的类型,其值是函数结果状态代码,如OK等 */
typedef struct Node
{
     
    int id;                                    //学号
    char name[20];                             //姓名 
    char sex;                                  //性别 
    char num[20];                              //手机号码 
    int math;                                  //数学分数 
    int chinese;                               //语文分数 
    struct Node *next;
}Node;

typedef struct Node *LinkList; 
Status InitList(LinkList *L);      //初始化链表 
Status ListEmpty(LinkList L);      //判断链表是否为空 
Status add(LinkList *L);           //在链表尾部添加结点 ,并更新文件 
Status deleteStu(LinkList *L);     //按学号删除其中某一个结点,并更新文件 
Status modify(LinkList *L);        //修改某一个结点,并更新文件 
Status get(LinkList *L);          //获取其中某一个或某一类结点 
Status sort(LinkList *L);          //给链表重排序打印,并更新文件 
Status ListTraverse(LinkList L);   //遍历链表,并打印 
Status countAll(LinkList *L);         //学生信息统计 
Status excelOut(LinkList *L);  //将链表导出保存为csv文件
void Print(Node c);                //结点打印函数 
void NewList(LinkList *L);         //创建指定数目的结点 
void excelIn(LinkList *L);      //从指定csv文件中导出数据,存入链表 
void menu(LinkList *L);            //主菜单界面 
int ListLength(LinkList L);

int ListLength(LinkList L)
{
     
    int i=0;
    LinkList p=L->next; /* p指向第一个结点 */
    while(p)                        
    {
     
        i++;
        p=p->next;
    }
    return i;
}
Status InitList(LinkList *L) 
{
      
    *L=(LinkList)malloc(sizeof(Node)); /* 产生头结点,并使L指向此头结点 */
    if(!(*L)) /* 存储分配失败 */
            return ERROR;
    (*L)->next=NULL; /* 指针域为空 */

    return OK;
}
/* 初始条件:顺序线性表L已存在。操作结果:若L为空表,则返回TRUE,否则返回FALSE */
Status ListEmpty(LinkList L)
{
      
    if(L->next)
            return FALSE;
    else
            return TRUE;
}
void Print(Node c)
{
     
    printf("%d ",c.id);
    printf("%s ",c.name);
    printf("%c ",c.sex);
    printf("%s ",c.num);
    printf("%d ",c.math);
    printf("%d\n",c.chinese);
}
//尾插法插入数据 
Status add(LinkList *L)
{
      
	LinkList p,e;
	p = *L;   
	e = (Node *)malloc(sizeof(Node)); /*  生成新结点 */
	printf("请输入学生信息,格式如下\n");
	printf("学号 姓名 性别(f/m) 电话 数学成绩 语文成绩\n");
	scanf("%d %s %c %s %d %d",&e->id,&e->name,&e->sex,&e->num,&e->math,&e->chinese);
	if(getchar()!='\n'){
     
		printf("输入错误,返回主界面\n");
		system("pause");
		return 0; 
	} 
	while (p->next)                            //循环寻找最后一个节点 
	{
     
		if((e->id)==(p->id))
		{
     
			printf("学生信息重复,返回界面\n");
			system("pause");
			return 0; 
		}
		p = p->next;
	}
	e->next = NULL;      
	p->next = e;          
	printf("添加成功\n");
	excelOut(L);
	return OK;
}
Status deleteStu(LinkList *L) 
{
      
	LinkList p;
	if(ListEmpty(*L)){
     
		printf("链表为空,请先输入数据\n");
		system("pause");
		return ERROR; 
	}//链表为空 
	p = (*L);
	int id;
	printf("输入待删除学生的学号\n");
	scanf("%d",&id);
	while (p->next&&(p->next->id!=id))	/* 寻找指向指定id的结点 */
	{
     
        p = p->next;
	}
	if (!(p->next)) {
     
		printf("不存在该学号的学生,删除失败\n");
		system("pause");
		return ERROR;   
	}                                   //不存在该学号的学生
	p->next = p->next->next;			//将该结点指向目标结点的后一个结点
	printf("删除成功\n");
	excelOut(L);                     //导出之Excel表 
	return OK;
}
//先查询出数据后进行修改 
Status modify(LinkList *L){
     
	LinkList p;
	p = (*L)->next;
	int id;
	if(ListEmpty(*L)){
     
		printf("链表为空,请先输入数据\n");
		system("pause");
		return ERROR; 
	}//链表为空  
	printf("输入待修改学生的学号\n");
	scanf("%d",&id);	
	while (p->id!=id)	/* 寻找指定id的结点 */
	{
     
        p = p->next;
	}
	if (p==NULL){
     
		printf("该学号的学生不存在\n");
		return ERROR;  
	} 	                                     /*  查询完整个链表,不存在该学号的学生 */
	printf("待修改学生信息为\n");
	Print(*p);
	printf("\n请选择修改项目\n");
	printf("1.修改学号\n");
	printf("2.修改姓名\n");
	printf("3.修改性别\n");
	printf("4.修改电话\n");
	printf("5.修改数学分数\n");
	printf("6.修改语文分数\n");
	printf("7.全部修改,重新输入\n");
	printf("8.取消修改\n");
	printf("请选择(1-8):[  ]\b\b"); 
	int i;
	scanf("%d",&i);
	switch(i){
     
		case 1:
			printf("将学号修改为\n");
			scanf("%d",&p->id);
			printf("修改后该学生信息为:\n");
			Print(*p);
			excelOut(L);
			break;
		case 2:
			printf("将姓名修改为\n");
			scanf("%d",&p->name);
			printf("修改后该学生信息为:\n");
			Print(*p);
			excelOut(L);
			break;
		case 3:
			printf("将性别修改为\n");
			scanf("%d",&p->sex);
			printf("修改后该学生信息为:\n");
			Print(*p);
			excelOut(L);
			break;
		case 4:
			printf("将电话号码修改为\n");
			scanf("%s",&p->num);
			printf("修改后该学生信息为:\n");
			Print(*p);
			excelOut(L);
			break;
		case 5:
			printf("将数学成绩修改为\n");
			scanf("%d",&p->math);
			printf("修改后该学生信息为:\n");
			Print(*p);
			excelOut(L);
			break;
		case 6:
			printf("将语文成绩修改为\n");
			scanf("%d",&p->chinese);
			printf("修改后该学生信息为:\n");
			Print(*p);
			excelOut(L);
			break;
		case 7:
			printf("将学生信息修改为\n");
			scanf("%d %s %c %s %d %d",&p->id,p->name,&p->sex,&p->num,&p->math,&p->chinese);
			printf("修改后该学生信息为:\n");
			Print(*p);
			excelOut(L);
			break;
		case 8:
			system("cls");
			modify(L);
		default:
			printf("输入错误,请重新输入\n");
			system("pause");
			system("cls");
			modify(L);
		 
	}
}
//待修改  按学号修改 
Status get(LinkList *L){
     
    int id;
    LinkList p=(*L)->next;
	if(ListEmpty(*L)){
     
		printf("链表为空,请先输入数据\n");
		system("pause");
		return ERROR; 
	}//链表为空 
    printf("输入待查询学生的学号\n");
    scanf("%d",&id); 
    while(p)
    {
     
        if(p->id==id){
     
        	printf("查询成功\n");
        	Print(*p);
        	system("pause");
            return OK;
		}       
        p=p->next;
    }
	printf("查询失败,不存在该学号的学生\n");
	system("pause");
    return ERROR;
}
//排序 
Status sort(LinkList *L){
     
	LinkList p,m,n,pre;
	int i;
	if(ListEmpty(*L)){
     
		printf("链表为空,请先输入数据\n");
		system("pause");
		return ERROR; 
	}//链表为空 
	int len=ListLength(*L);
	int j=0;
	printf("\t\t1.按学号排序\n");
	printf("\t\t2.按数学成绩排序\n");
	printf("\t\t3.按语文成绩排序\n");
	printf("\t\t请选择(1-3):[  ]\b\b\b");
	scanf("%d",&i);
	printf("开始排序\n");
	switch(i){
     
		case 1:
			while(j<len-1){
     
				p=*L;
				while((p->next!=NULL)&&(p->next->next!=NULL)){
     
					if((p->next->id)>(p->next->next->id)){
     
						m=p->next->next;
						n=p->next;
						p->next=m;
						n->next=m->next;
						m->next=n;
					}
					p=p->next;
				}
				j=j+1;
			}
			printf("排序成功");
			printf("重排序后为\n"); 
			ListTraverse(*L);
			excelOut(L);
			break;
		case 2:
			while(j<len-1){
     
				p=*L;m=*L;n=*L;
				while((p->next!=NULL)&&(p->next->next!=NULL)){
     
					if((p->next->math)<(p->next->next->math)){
     
						m=p->next->next;
						n=p->next;
						p->next=m;
						n->next=m->next;
						m->next=n;
					}
					p=p->next;
				}
				j=j+1;
			}
			printf("排序成功");
			printf("重排序后为\n"); 
			ListTraverse(*L);
			excelOut(L);
			break;
		case 3:
			while(j<len-1){
     
				p=*L;m=*L;n=*L;
				while((p->next!=NULL)&&(p->next->next!=NULL)){
     
					if((p->next->chinese)<(p->next->next->chinese)){
     
						m=p->next->next;
						n=p->next;
						p->next=m;
						n->next=m->next;
						m->next=n;
					}
					p=p->next;
				}
				j=j+1;
			}
			printf("排序成功");
			printf("重排序后为\n"); 
			ListTraverse(*L);
			excelOut(L);
			break;
		default:
			printf("无效输入,请重新输入\n");
			system("pause");
			system("cls");
			sort(L);
	}
	return 0;
}
//遍历数据,用于检测数据 
Status ListTraverse(LinkList L)
{
     
	if(ListEmpty(L)){
     
		printf("链表为空,请先输入数据\n");
		system("pause");
		return ERROR; 
	}//链表为空  
    LinkList p=L->next;
    while(p)
    {
     
        Print(*p);
        p=p->next;
    }
    system("pause"); 
    return OK;
}
void NewList(LinkList *L) 
{
     
	LinkList p,r;
	int i,n;
	printf("输入学生的数量:\n");
	scanf("%d",&n);
	*L = (LinkList)malloc(sizeof(Node)); /* L为整个线性表 */
	r=*L;                                /* r为指向尾部的结点 */
	printf("请输入学生信息,格式如下\n");
	printf("学号  姓名  性别(m\f)  号码   数学成绩  语文成绩\n");
	for (i=0; i<n; i++) {
     
		printf("%d:  ",i+1);	
		p = (Node *)malloc(sizeof(Node)); /*  生成新结点 */
		scanf("%d %s %c %s %d %d",&p->id,p->name,&p->sex,&p->num,&p->math,&p->chinese);  
		if(p->sex!='m'&&p->sex!='f')
	{
     
		printf("性别输入错误");
		system("pause");
		return ;
	}
		r->next=p;                        
		r = p;                            
	}
	r->next = NULL;                       /* 表示当前链表结束 */
	printf("输入结束\n");
	system("pause"); 
}

//拓展功能
Status countAll(LinkList *L){
     
	if(ListEmpty(*L)){
     
		printf("链表为空,请先输入数据\n");
		system("pause");
		return 0; 
	}//链表为空 
	printf("学生信息情况统计如下:\n"); 
	LinkList p;
	p = (*L)->next;
	int male,female,num;
	int badmale=0,okmale=0,okkmale=0,goodmale=0,badfemale=0,okfemale=0,okkfemale=0,goodfemale=0,summath=0,sumchinese=0,averagemath=0,averagechinese=0;
	//男生人数,女生人数,总人数和不及格(<60),及格(60-70),良好(70-90),优秀(90-100)分数标准 
	double radio;
	while(p){
     
		num=num+1;
		if(p->sex=='m'){
     
			male=male+1;
		}else{
     
			female=female+1;
		}
		switch(p->math/10){
     
			case 1:
			case 2:
			case 3:
			case 4:
			case 5:
				badmale=badmale+1;
				break;
			case 6:
				okmale=okmale+1;
				break;
			case 7:
			case 8:
			case 9:
				okkmale=okkmale+1;
			case 10:
				goodmale=goodmale+1;
				
		}
		switch(p->chinese/10){
     
			case 1:
			case 2:
			case 3:
			case 4:
			case 5:
				badfemale=badfemale+1;
				break;
			case 6:
				okfemale=okfemale+1;
				break;
			case 7:
			case 8:
			case 9:
				okkfemale=okkfemale+1;
			case 10:
				goodfemale=goodfemale+1;	
		}
		summath=summath+p->math;
		sumchinese=sumchinese+p->chinese;
		p=p->next;
	}
	printf("总人数为 %d\n",num);
	printf("男生人数为 %d\n",male);
	printf("女生人数为 %d\n",female);
	radio=male*1.0/num;
	printf("男女比例为 %.1f : %.1f\n",radio,(1-radio));
	printf("数学成绩\n");
	printf("不及格: %d人\t",badmale);
	printf("及格: %d人\t",okmale);
	printf("良好: %d人\t",okkmale);
	printf("优秀: %d人\n",goodmale);
	averagemath=summath*1.0/num;
	printf("数学成绩平均分为:  %d\n",averagemath);
	printf("语文成绩\n");
	printf("不及格: %d人\t",badfemale);
	printf("及格: %d人\t",okfemale);
	printf("良好: %d人\t",okfemale);
	printf("优秀: %d人\n",goodfemale);
	averagechinese=sumchinese/num;
	printf("语文成绩平均分为:  %d\n",averagechinese);
	system("pause");
	return 1;
}

Status excelOut(LinkList *L){
     
	if(ListEmpty(*L)){
     
		printf("链表为空,导出失败\n");
		system("pause");
		return 0; 
	}                                   //链表为空 
	FILE *fp=NULL;
	fp=fopen("C:\\Users\\86150\\Desktop\\ttt.csv","w+");
	LinkList p;
	p=(*L)->next;
	printf("开始保存\n");
	while(p){
     
		fprintf(fp,"%d,%s,%c,%s,%d,%d\n",p->id,p->name,p->sex,p->num,p->math,p->chinese);
		p=p->next;
	}
	printf("保存成功\n"); 
	system("pause"); 
	fclose(fp);
	return 1;
}

void excelIn(LinkList *L){
     
	FILE *fp;
	fp=fopen("C:\\Users\\86150\\Desktop\\3.csv","r");
	LinkList p,e,next;
	p=(*L);
	printf("开始读入\n");
	while(!feof(fp)){
     
		e = (Node *)malloc(sizeof(Node)); /*  生成新结点 */	
		fscanf(fp,"%d,%2s,%c,%11s,%d,%d\n",&e->id,e->name,&e->sex,e->num,&e->math,&e->chinese);
		e->next=NULL;
		p->next=e;
		p=p->next;
	}
	printf("读入成功\n"); 
	system("pause"); 
	fclose(fp);
}

void menu(LinkList *L){
     
	int n;
	printf("\t---------------学生个人信息管理系统---------------\n");
	printf("\t\t\t1.创建学生管理系统(手动输入创建)\n");
	printf("\t\t\t2.添加学生信息\n");
	printf("\t\t\t3.删除学生信息\n");
	printf("\t\t\t4.修改学生信息\n");
	printf("\t\t\t5.查询学生信息\n");
	printf("\t\t\t6.排序后输出\n");
	printf("\t\t\t7.信息检查\n");
	printf("\t\t\t8.信息统计\n");
	printf("\t\t\t9.Excel数据导入\n");
	printf("\t\t\t10.Excel数据导出\n");
	printf("\t\t\t11.退出\n");
	printf("\t\t\t请选择(1-11):[  ]\b\b\b");
	scanf("%d",&n); 
	switch(n){
     
		case 1:
			system("cls");
			NewList(L);//初始化学生管理系统,输入指定数目的学生信息 
			break;
		case 2:
			system("cls");
			add(L);//添加学生信息 
			break;
		case 3:
			system("cls");
			deleteStu(L);//删除指定学生 
			break;
		case 4:
			system("cls");
			modify(L);//修改学生信息 
			break;
		case 5:
			system("cls");
			get(L);//查找指定学生 
			break;
		case 6:
			system("cls");
			sort(L);//排序输出 
			break;
		case 7:
			system("cls");
			ListTraverse(*L);//遍历 
			break;
		case 8:
			system("cls");
			countAll(L);
			break;//学生信息情况统计 
		case 9:
			system("cls");
			excelIn(L);
			break;
		case 10:
			system("cls");
			excelOut(L);
			break;
		case 11:
			exit(0);
		default :
			system("cls");
			printf("无效输入,请重新输入\n");
			system("pause"); 
			break;
	} 
}

int main(){
     
	LinkList stu;
	InitList(&stu); 
	while(1){
     
		system("cls");
		menu(&stu);
	}	
}

你可能感兴趣的:(链表,学生信息管理系统,数据结构)