C语言学生管理系统

C语言学生管理系统

源代码

#define _CRT_SECURE_NO_DEPRECATE 
#include <stdio.h>   
#include <malloc.h> 
#include <string.h> 
#include <stdlib.h>
#include <iostream>
using namespace std;

// 定义结构体并别名NODE
typedef struct node	
{
	struct node* next;
	// 学号
	int num; 
	// 姓名
	char name[100];
	// 年龄
	int age;
}NODE;

// 声明函数 
char menu1();
NODE* createn();
void traveln(NODE* head);
NODE* appendn(NODE* head, int num, char name[100], int age);
void saveStuInfo(NODE* head);
NODE* readStuInfo(NODE* head);
NODE* del2n(NODE* head, int num);
NODE* findn(NODE* head, int num);
NODE* insertn(NODE* head, int num,char name[100], int age);
NODE* updateStuInfo(NODE* head, int num,char name[100], int age);


int main()
{
	char m = '0';
	NODE* head = NULL;
	head = readStuInfo(head);
	//	initn(head);
	// 学号,年龄
	int num,age; 
	// 姓名
	char name[100];
	while (m != '6')
	{
		m = menu1();
		// 是否操作标志 
		char flag = 'n';
		switch (m)
		{
		case '1':
			printf("\n\n\t请输入学号:");
			cin >> num;
			printf("\n\n\t请输入姓名:");
			cin >> name;
			printf("\n\n\t请输入年龄:");
			cin >> age;
			head = appendn(head, num, name, age);
			saveStuInfo(head);
			cout << "\n\t添加成功" << endl;
			cout << "\t是否返回菜单继续操作(y/n)";
			flag = 'n';
			cin >> flag;
			if (flag != 'y') {
				exit(0);
			}
			break;
		case '2':  
			traveln(head);
			cout << "\t是否返回菜单继续操作(y/n)";
			flag = 'n';
			cin >> flag;
			if (flag != 'y') {
				exit(0);
			}
			break;
		case '3':	printf("\n\n\t请输入学号:");
			cin >> num;
			del2n(head,num);
			cout << "\n\t删除成功\n" << endl;
			cout << "\t是否返回菜单继续操作(y/n)";
			flag = 'n';
			cin >> flag;
			if (flag != 'y') {
				exit(0);
			}
			break;
		case '4':	
			printf("\n\n\t请输入要修改学号:");
			cin >> num;
			printf("\n\n\t请输入姓名:");
			cin >> name;
			printf("\n\n\t请输入年龄:");
			cin >> age;
			updateStuInfo(head,num,name,age);
			cout << "\n\t修改成功\n" << endl;
			cout << "\t是否返回菜单继续操作(y/n)";
			flag = 'n';
			cin >> flag;
			if (flag != 'y') {
				exit(0);
			}
			break;
		case '5':
			printf("\n\n\t请输入要查询学生的学号:");
			cin >> num;
			NODE* seachHead = findn(head,num);
			cout << "\n\t学生基本信息\n" << endl;
	cout << "\t------------------------------------------------------------------------------\n" <<endl;
	cout << "\t\t学号\t\t\t\t姓名\t\t\t\t年龄\n";
		// 判断链表尾									
			//cout << "head=" << head << endl;
			cout << "\n\t\t" << seachHead->num;
			cout <<"\t\t\t\t" << seachHead->name;
			cout << "\t\t\t\t" << seachHead->age << "\n";		
	cout << "\n\t------------------------------------------------------------------------------\n" <<endl;																
			cout << "\t是否返回菜单继续操作(y/n)";
			flag = 'n';
			cin >> flag;
			if (flag != 'y') {
				exit(0);
			}
			break;
		}
	}
	printf("\n\n\t退出成功");
}
// 自编的菜单函数
char menu1()							
{
	char c;
	// 清屏
	// system("cls");		
	// 清输入队列
	fflush(stdin);						
	printf("\n\n\t 学生信息管理系统 \n");
	printf("\n\n\t ============= 菜单列表 =============\n");
	// 显示菜单选项1
	printf("\n\n\t 1-学生基本信息录入与保存");	
	// 显示菜单选项2
	printf("\n\n\t 2-学生基本信息的显示");				
	printf("\n\n\t 3-学生基本信息的删除");
	printf("\n\n\t 4-学生基本信息的修改");
	printf("\n\n\t 5-学生基本信息的查询");
	// 显示菜单选项5-退出
	printf("\n\n\t 6-退出系统\n");
	do										
	{
		// 输入,并排除非法按键
		printf("\n\n\t 请输入菜单列表前的序号 : ");
		cin >> c;
		if (c < '0' || c>'6')
			printf("\n\n\t 输入的数字不在菜单列表内,请重新输入\n");
	} while (c < '0' || c>'6');
	return c;
}
// 保存文件
void saveStuInfo(NODE* head)//保存学生信息到文件  
{
	FILE* fp;
	NODE* p = head;
	if ((fp = fopen("student.txt", "w")) == NULL)// 以可写的方式打开当前目录下的.txt  
	{
		printf("不能打开此文件,请按任意键退出\n");
		exit(1);  //异常退出
	}
	while (p)
	{
		fprintf(fp, "%d %s %d \n", p->num, p->name, p->age);
		p = p->next;
	}
	fclose(fp);
}
NODE* readStuInfo(NODE* head) //运行前把文件内容读取到电脑内存  
{
	FILE* fp;
	fp = fopen("student.txt", "rb+"); 
	
	if (fp == NULL)
	{
		printf("文件不存在,添加数据后将自动创建\n");
		return head; 
//		exit(0);                   //终止程序  
	}
	
	int nu;//学号  
	char nam[100];//名字 
	int ag;//年龄  
	fscanf(fp, "%d %s %d", &nu,nam,&ag);
	NODE* n = (NODE*)malloc(sizeof(NODE));
	NODE* p;
	n->num = nu;
	strcpy(n->name, nam);//把后者的内容拷贝到前者中  
	n->age = ag;
	n->next = NULL;
	head = n;
	p = head;
	while (!feof(fp))
	{
		fscanf(fp, "%d %s %d", &nu,nam,&ag);
		if (feof(fp)) break;
		NODE* n = (NODE*)malloc(sizeof(NODE));
		n->num = nu;
		strcpy(n->name, nam);//把后者的内容拷贝到前者中  
		n->age = ag;
		n->next = NULL;
		p->next = n;
		p=n;
		
		
	}
	cout << "\t读取文件数据成功,数据如下:\n" << endl;
	traveln(head);
	fclose(fp);
	return head;

}
// 产生一个新链表,仅1节点
NODE* createn()							
{
	NODE* head = NULL;
	// 新申请一个节点空间
	head = (NODE*)malloc(sizeof(NODE));		
	if (head == NULL)
	{
		printf("申请空间出错。");
		exit(1);
	}
	// 新建的唯一节点也是头、也是尾
	head->next = NULL;							
	// 可以在此加语句输入数据						
	return head;
}
//遍历整个链表
void traveln(NODE *head)									
{
	if (head == NULL)
		printf("\t空数据 \n\n");
	else
	
	cout << "\n\t学生基本信息\n" << endl;
	cout << "\t------------------------------------------------------------------------------\n" <<endl;
	cout << "\t\t学号\t\t\t\t姓名\t\t\t\t年龄\n";
		// 判断链表尾
		while (head != NULL)									
		{
			//cout << "head=" << head << endl;
			cout << "\n\t\t" <<head->num;
			cout <<"\t\t\t\t" <<head->name;
			cout << "\t\t\t\t" <<head->age << "\n";		
			// 移动指针
			head = head->next;								
		}
	cout << "\n\t------------------------------------------------------------------------------\n" <<endl;
}
 //在链表尾部添加节点
NODE* appendn(NODE *head, int num, char name[100], int age)
{
	NODE *p, *q;
	if (head == NULL)
	{
		head = createn();
		head->num = num;
		strcpy(head->name, name);
		head->age = age;
	}
	else
	{
		p = head;
		// 移动到链表尾,准备后面添加
		while (p->next != NULL)							
			p = p->next;
		// 新申请一个节点空间
		q = (NODE*)malloc(sizeof(NODE));				
		if (q == NULL)
		{
			printf("申请空间出错。");
			exit(1);
		}
		// 新建节点是尾
		q->next = NULL;		
		// 添加到原链表尾
		p->next = q;										
		q->num = num;
		strcpy(q->name, name);
		q->age = age;
	}
	// 有返回值是因为为了处理空链表,否则可以不要
	return head;				
}
NODE* insertStu(NODE *head)
{
	NODE *p, *q;
	if (head == NULL)
	{
		return NULL;
	}
	else
	{
		p = head;
		// 移动到链表尾,准备后面添加
		while (p->next != NULL)							
			p = p->next;
		// 新申请一个节点空间
		q = (NODE*)malloc(sizeof(NODE));				
		if (q == NULL)
		{
			printf("申请空间出错。");
			exit(1);
		}
	}
	// 有返回值是因为为了处理空链表,否则可以不要
	return head;				
}
NODE* del2n(NODE* head, int num)	// 在链表中删除多个节点
{
	NODE* p = head, * q;
	if (p != NULL)
	{
		while (head != NULL && head->num == num)	// 如果头节点就是要删除对象
		{
			head = p->next;
			free(p);
			p = head;
		}
		while (p != NULL)
		{
			q = p;
			p = p->next;
			if (p != NULL && p->num == num)	// 删除一个中间节点
			{
				q->next = p->next;
				free(p);
				p = q;
			}
		}
	}
	saveStuInfo(head);
	return head;	// 返回值是链表头
}

NODE* insertn(NODE* head, int num,char name[100], int age)	// 在链表某节点后插入1个节点
{
	NODE* p, * q;
	if (head == NULL)
	{
		head = createn();
		head->num = num;
		strcpy(head->name, name);
		head->age = age;
	}
	else
	{
		p = head;
		while (p->next != NULL && p->num != num) // 移动到位置,准备后面添加
			p = p->next;
		q = (NODE*)malloc(sizeof(NODE));	// 新申请一个节点空间
		if (q == NULL)
		{
			printf("申请空间出错。");
			exit(1);
		}
		q->next = p->next;		// 插入新建节点
		p->next = q;			// 添加到位置后
		q->num = num;
		q->age = age;			// 将实参数据加入
		strcpy(q->name, name);
	}
	return head;				// 有返回值是因为为了处理空链表,否则可以不要
}
NODE* updateStuInfo(NODE* head, int num,char name[100], int age)	// 在链表某节点后插入1个节点
{
	NODE* p;
	if (head == NULL)
	{
		head = createn();
		head->num = num;
		strcpy(head->name, name);
		head->age = age;
	}
	else
	{
		p = head;
		while (p->next != NULL && p->num != num)	// 移动到位置,准备后面添加
			p = p->next;							// 添加到位置后
		p->age = age;								// 将实参数据加入
		strcpy(p->name, name);
	}
	saveStuInfo(head);
	return head;		// 有返回值是因为为了处理空链表,否则可以不要
}
NODE* findn(NODE* head, int num)					// 在链表中查找1个节点
{
	while (head != NULL && head->num != num)
		head = head->next;
	return head;									// 返回值是找到的节点的指针
}

需求分析

设计的学生信息管理系统是用户管理学生的信息,通过文件存储学生信息数据,通过交互实现对学生基本信息的录入和存取,并且可以浏览学生的相关信息,然后可以删除和插入学生的相关信息,同时可以按学号查询此学生的相关信息。

概要设计

菜单界面与各模块间的结构关系图。学生信息管理系统由六个模块组成,系统的模块结构如图1所示。

详细设计

学生基本信息录入和保存

在菜单输入 1,进入学生信息录入,依次输入学号,姓名,年龄,回车就能保存。具体流程为创建一个链表,判断头节点是否为空,为空就重新创建,申请新的节点空间,将 next 设置为 NULL,有了链表,一直循环到链表最后,也就是 next 为 NULL,接着申请一个节点存放学生信息,然后连接起来。

学生基本信息的显示

先读取文件数据,如果文件有数据会存入 head 中,之后判读链表是否有数据,没有则打印空数据,有数据就遍历链表,循环打印每个节点的数据,并向后移动指针,直到全部打印完毕。

学生基本信息的删除

读取文件数据,输入学号,遍历链表,移动指针,找到节点学号和输入的学号相同的节点,删除节点,上一个节点指向下个节点,最后保存到文件中。

学生基本信息的修改

读取文件数据,输入学号,姓名,年龄,传入链表,判断链表是否存在,不存在则创建新链表,存在就找到节点学号数据与输入学号相同的节点,修改节点中的数据,保存到文件中。

学生基本信息的查询

传入链表,输入学生学号,判断链表是否存在,存在就找到节点学号数据与输入学号相同的节点,打印出学生信息。

退出系统

菜单编号是 6 ,如果退出,则打印退出成功。

流程图

录入学生基本数据流程

学生基本信息的显示

学生基本信息删除

学生基本信息修改

学生基本信息查询

退出系统

运行截图

菜单页面可以选择不同的学生基本信息操作,下图分别是数据读取,菜单界面,学生的添加,文件保存以及学生数据的展示。

读取文件加载学生信息

查询单个学生数据

添加学生信息

显示学生信息(包括文件中的信息)

删除学生基本信息

修改学生基本信息

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

凉了的凉茶

你的鼓励将是我创作的最大动力

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

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

打赏作者

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

抵扣说明:

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

余额充值