学生信息管理系统——C语言版本(易懂)

一、功能概述

        1.账号的登录与注册

        2.学生信息的增添

        3.学生信息对于学号的排序

        4.学生信息的删除

        5.学生信息的修改

        6.学生信息的查找

        7.学生信息的分类

        8.学生信息表的打印

        9.结束程序时对信息的在内存中的保存

        10.执行程序时对保存在内存当中的信息的读取

        11.构建菜单

二、流程图

 

三、功能实现详解

        1.文件信息的读取与保存

void saveInfoToFile(char* fileName, InfoSys* pc)
{
	FILE* fp = fopen(fileName,"w");
	if (fp == NULL)
	{
		perror("fopen");
		return;
	}
	InfoSys* cur =pc->next;
	while (cur)
	{
		fprintf(fp, "%s %s %s %d %lf %s %s\n", cur->ID, cur->name, cur->sex,
                     cur->age, cur->score, cur->professional, cur->clas);
		cur = cur->next;
	}

	fclose(fp);
	fp = NULL;
	return;
}
void readInfoFromFile(char* fileName, InfoSys* pc)
{
	FILE* fp = fopen(fileName,"r");
	int ch=fgetc(fp);
	if (ch == EOF)
	{
		return;
	}
	fseek(fp,0,SEEK_SET);
	if (fp == NULL)
	{
		perror("fopen");
		return;

	}
	InfoSys* temp = (InfoSys*)malloc(sizeof(InfoSys));
	InfoSys* cur = pc;

	cur->next = NULL;
	pc->next = cur;
	
	while (fscanf(fp, "%s %s %s %d %lf %s %s", temp->ID, temp->name, temp->sex, 
                        &(temp->age), &(temp->score), temp->professional, 
                        temp->clas) != EOF)
	{
		InfoSys* next = (InfoSys*)malloc(sizeof(InfoSys));
		next->next = NULL;
		cur->next = next;
		cur = next;
		strcpy(cur->ID, temp->ID);
		strcpy(cur->name, temp->name);
		strcpy(cur->sex, temp->sex);
		cur->age = temp->age;
		cur->score = temp->score;
		strcpy(cur->professional, temp->professional);
		strcpy(cur->clas, temp->clas);
		
		//这一块空间是被需要的,不用free;
	}
	
	fclose(fp);
	fp = NULL;
	free(temp);
	temp = NULL;
	return;

}

2.账号的登录与注册

        可以实现对注册账号在文件中的保存和读取,在登录时,实现掩码操作

int isUserValid(char* userAccount, char* userPassword)
{
	FILE* fp = fopen("UserInfo.txt","r");
	char UAt[USERACCOUNTNUM];
	char UPd[USERPASSWORDNUM];
	char temp[USERPASSWORDNUM];
	if (fgetc(fp) == EOF)
	{
		printf("无此账号,请重新输入.....\n");
		fclose(fp);
		fp = NULL;
		return 0;
	}
	fseek(fp,-1,SEEK_CUR);
	while (strcmp(fgets(UAt, USERACCOUNTNUM, fp), userAccount) != 0)
	{
		fgets(temp, USERACCOUNTNUM, fp);

		if (fgetc(fp)==EOF)
		{
			
			printf("无此账号,请重新输入.....\n");
			fclose(fp);
			fp = NULL;
			return 0;
		}
		else
		{
			fseek(fp, -1, SEEK_CUR);
		}
	}
	if (strcmp(UAt, userAccount) == 0)
	{
		fgets(UPd, USERPASSWORDNUM, fp);
		if((strcmp(UPd, userPassword) == 0))
		{
			printf("\t\t欢迎进入管理系统,请稍后......\n");
			Sleep(1000);
			fclose(fp);
			fp = NULL;
			return 1;
		}
		else
		{
			printf("密码输入错误,请重新输入......\n");
			fclose(fp);
			fp = NULL;
			return 0;
		}
	}
	

}
void enroll_menu()
{
	head_menu();
	printf("\n\n\n");
	printf("\t\t用户注册,请输入账号、密码......\n\n");
}
void login_menu()
{
	head_menu();
	printf("\n\n\n");
	printf("\t\t用户登录,请输入账号、密码......\n\n");
	return;
}
void enroll()
{
	FILE* fp = fopen("UserInfo.txt","a");
	char userAccount[USERACCOUNTNUM];
	char userPassword[USERPASSWORDNUM];
	if (fp == NULL)
	{
		perror("fopen");
		return;
	}
	getchar();
	enroll_menu();
	printf("\t\t账号:>");
	int i;
	for (i = 0; i < USERACCOUNTNUM; i++)
	{
		userAccount[i] = getchar();
		if (userAccount[i] == '\n')
		{
			break;
		}
	}
	userAccount[i] = '\0';
	printf("\t\t密码:>");
	for (i = 0; i < USERPASSWORDNUM; i++)
	{
		userPassword[i] = getchar();
		if (userPassword[i] == '\n')
		{
			break;
		}
	}
	userPassword[i] = '\0';
	fprintf(fp,"%s",userAccount);
	fputc('\n',fp);
	fprintf(fp,"%s",userPassword);
	fputc('\n\n\n', fp);

	printf("\n\n注册成功.....");
	printf("\n\n请退出程序重新运行......");
	Sleep(1000);
	fclose(fp);
	fp = NULL;
}
int login()
{
	char userPassword[USERPASSWORDNUM], userAccount[USERACCOUNTNUM];
	int i;
	/*login_menu();*/
	getchar();
	printf("\t\t账号:>");
	for (i = 0; i < USERACCOUNTNUM; i++)
	{
		userAccount[i] =getchar();
		if (userAccount[i] == '\n')
		{
			break;
		}
	}
	userAccount[++i] = '\0';
	printf("\t\t密码:>");
	for (i = 0; i < USERPASSWORDNUM; i++)
	{
		userPassword[i] = _getch();
		if (userPassword[i] == '\r')//回车
		{
			break;
		}
		printf("*");//掩码处理
	}
	userPassword[i] = '\n';
	userPassword[++i] = '\0';

	if (isUserValid(userAccount, userPassword) == 1)
	{
		return 1;
	}
	else
	{
		return 0;
	}
}

3.菜单的构建(为了方便对基础功能的种类的了解,先说菜单)

        以下包括了登录菜单和选择菜单,下文出现的功能如图所示

void welcome_menu()
{
	printf("\n\n\n");
	printf("\t                                           ╔═════════════╗\n");
	printf("\t                                           ║      (\\  (\\ ║\n");
	printf("\t                                           ║      (-。-) ║\n");
	printf("\t                                           ║      。_(\") ║\n");
	printf("\t                                           ╚═════════════╝\n");
	printf("\t                                        *欢迎使用信息管理系统*\n");
	printf("\t                                 ····SWPU猪皮兄弟为你服务····\n");
	printf("\n\n\n");
	system("pause");
	
}

void main_menu()
{
	printf("\t\t| * * * * * * * 信息管理系统 * * * * * * |\n");
	printf("\t\t|……………………………………………………|\n");
	printf("\t\t| 请选择操作菜单序号(0-6) |\n");
	printf("\t\t|……………………………………………………|\n");
	printf("\t\t| 1----学生信息录入 |\n");
	printf("\t\t| 2----学生信息排序 |\n");
	printf("\t\t| 3----学生信息查询 |\n");
	printf("\t\t| 4----学生分类查询 |\n");
	printf("\t\t| 5----学生信息删除 |\n");
	printf("\t\t| 6----学生信息修改 |\n");
	printf("\t\t| 7----学生信息打印 |\n");
	printf("\t\t| 0----   退 出     |\n");
	printf("\t\t|……………………………………………………|\n");
	printf("\t\t| * * * * * * * * * * * * * * * * * * *  |\n");
	printf("\n\t请选择序号: ");

}

4.学会信息管理的基础操作(增删查改、打印列表、排序)

        对这部分的实现,采用的是单链表的结构

1.打印列表和退出程序

void showMessge(InfoSys * pc)
{
	printf("                             ~~~~~    学生信息表    ~~~~~\n");
	printf(" ---------------------------------------------------------------------------------------\n");
	printf("%-12s\t%-9s\t%-4s\t%-4s\t%-9s\t%-9s\t%-7s\n","学号","姓名","性别","年龄","成绩","专业","班级");
	InfoSys* cur = pc->next;
	while (cur!=NULL)
	{
		printf("%-12s\t%-9s\t%-4s\t%-4d\t%-9.2lf\t%-9s\t%-7s\n", cur->ID, cur->name, 
                    cur->sex, cur->age, cur->score, cur->professional, cur->clas);
		cur = cur->next;

	}
	return;
}
void Exit()
{
	exit(-1);
}

2.增添学生信息

void Add(InfoSys* pc)
{
	
	InfoSys* cur = pc->next;
	char ID[IDNUM];
	char name[NAMENUM];
	char sex[SEXNUM];
	int age;
	double score;
	char professional[PROFESSIONALNUM];
	char clas[CLASNUM];
	
	while(1)
	{
		printf("请依次输入:>  学号 - 姓名 - 性别 - 年龄 - 成绩 - 专业 - 班级\n");
		scanf("%s %s %s %d %lf %s %s", ID, name, sex, &age, &score, professional, clas);
		InfoSys* newnode = CreateNode(ID, name, sex, age, score, professional, clas);
		if (cur == NULL)
		{
			pc->next = newnode;
		}
		else
		{
			while (cur->next != NULL)
			{
				cur = cur->next;
			}
			cur->next = newnode;
		}
		printf("请选择是否继续添加:>(Y/N)\n");
		char input;
		rewind(stdin);//让下面的scanf不受缓存区的影响
		scanf("%c",&input);//这里的scanf直接跳过的问题,用以上方法
		if (input == 'Y')
		{
			continue;
		}
		else 
		{
			break;
		}
	} 
	
	return;
}

        注意一定要在第二个scanf之前rewind(stdio),不然这个scanf会读取缓冲区里面的\n就等于是直接跳过。

3.删除学生信息

void Del(InfoSys* pc)
{
	InfoSys* cur = pc->next;
	InfoSys* prev = pc;
	char ID[IDNUM] = { 0 };
	printf("请输入要删除学生的学号: \n");
	int count = 0;
	scanf("%s",ID);
	while (cur)
	{
		if (strcmp(cur->ID, ID) == 0)
		{
			prev->next=cur->next;
			free(cur);
			count++;
			cur = NULL;
		}
		else
		{
			cur = cur->next;
			prev = prev->next;
		}
	}
	if (count == 0)
	{
		printf("未找到该学生信息......\n");
		system("pause");
		return;
	}	
	printf("删除成功......\n");
	return;

	
	
}

4.对学生信息进行排序(这里采用冒泡排序的思想)

void Sort(InfoSys* pc)//实际中都是按学号排序//代码未实现,需要多次进行排序操作
{

	InfoSys* prev, * cur, * next;
	int count=0;
	cur = pc->next;
	while (cur != NULL)
	{
		count++;
		cur = cur->next;
	}
	if (count == 1)
	{
		printf("排序成功......\n");
		return;
	}
	else if (count == 0)
	{
		printf("列表中无学生信息\n");
		return;
	}
	else
	{
		
		for (int i = 0; i < count-1; i++)
		{
			prev = pc;
			cur = pc->next;
			next = cur->next;
			while (next != NULL)
			{
				if (strcmp(cur->ID, next->ID) > 0)
				{
					cur->next = next->next;
					prev->next = next;
					next->next = cur;
					next = cur->next;
					prev = prev->next;
				}
				else
				{
					next = next->next;
					cur = cur->next;
					prev = prev->next;
				}
			}
		}

	}
	printf("排序成功......\n");
	return;
}

5.查询与分类查询

普通查询(按学号进行查找)

void Search(InfoSys* pc)
{
	printf("请输入要查找学生的学号\n");
	char ID[IDNUM] = { 0 };
	InfoSys* cur = pc->next;
	int count = 0;
	scanf("%s",ID);
	printf("                             ~~~~~    学生信息表    ~~~~~\n");
	printf(" ---------------------------------------------------------------------------------------\n");
	printf("%-12s\t%-9s\t%-4s\t%-4s\t%-9s\t%-9s\t%-7s\n", "学号", "姓名", "性别", "年龄", "成绩", "专业", "班级");
	while (cur != NULL)
	{
		if (strcmp(cur->ID, ID) == 0)
		{
			
			printf("%-12s\t%-9s\t%-4s\t%-4d\t%-9.2lf\t%-9s\t%-7s\n", cur->ID, cur->name, cur->sex, cur->age, cur->score, cur->professional, cur->clas);
			count++;
		}
		cur = cur->next;
	}
	if(count ==0)
	printf("未找到该学生信息......\n");
	return;
}

分类查询

void ClassifySearch(InfoSys* pc)
{
	printf("                     学生分类......\n");
	printf("------------------------------------------------------\n");
	printf("1.姓名   2.性别    3.年龄   4.成绩    5.专业    6.班级\n");
	printf("请输入要分的类型(1-6):\n");
	int input;
	scanf("%d",&input);
	switch (input)
	{
	case 1:
	{
		printf("请输入需要查找的姓名:");
		char name[NAMENUM] = { 0 };
		scanf("%s", name);
		InfoSys* cur = pc->next;
		if (cur == NULL)
		{
			printf("未查询到相关信息......\n");
			break;
		}
		printf("                             ~~~~~    学生信息表    ~~~~~\n");
		printf(" ---------------------------------------------------------------------------------------\n");
		printf("%-12s\t%-9s\t%-4s\t%-4s\t%-9s\t%-9s\t%-7s\n", "学号", "姓名", "性别", "年龄", "成绩", "专业", "班级");
		while (cur != NULL)
		{
			if (strcmp(cur->name, name) == 0)
			{
				printf("%-12s\t%-9s\t%-4s\t%-4d\t%-9.2lf\t%-9s\t%-7s\n", cur->ID, cur->name, cur->sex, cur->age, cur->score, cur->professional, cur->clas);
			}
			cur = cur->next;
		}

		break;
	}
	case 2:
	{
		printf("请输入需要查找的姓别:");
		char sex[SEXNUM] = { 0 };
		scanf("%s", sex);
		InfoSys* cur = pc->next;
		if (cur == NULL)
		{
			printf("未查询到相关信息......\n");
			break;
		}
		printf("                             ~~~~~    学生信息表    ~~~~~\n");
		printf(" ---------------------------------------------------------------------------------------\n");
		printf("%-12s\t%-9s\t%-4s\t%-4s\t%-9s\t%-9s\t%-7s\n", "学号", "姓名", "性别", "年龄", "成绩", "专业", "班级");
		while (cur != NULL)
		{
			if (strcmp(cur->sex, sex) == 0)
			{
				printf("%-12s\t%-9s\t%-4s\t%-4d\t%-9.2lf\t%-9s\t%-7s\n", cur->ID, cur->name, cur->sex, cur->age, cur->score, cur->professional, cur->clas);
			}
			cur = cur->next;
		}
		break;
	}
	case 3:
	{
		printf("请输入需要查找的年龄:");
		int age;
		scanf("%d", &age);
		InfoSys* cur = pc->next;
		if (cur == NULL)
		{
			printf("未查询到相关信息......\n");
			break;
		}
		printf("                             ~~~~~    学生信息表    ~~~~~\n");
		printf(" ---------------------------------------------------------------------------------------\n");
		printf("%-12s\t%-9s\t%-4s\t%-4s\t%-9s\t%-9s\t%-7s\n", "学号", "姓名", "性别", "年龄", "成绩", "专业", "班级");
		while (cur != NULL)
		{
			if (cur->age == age)
			{
				printf("%-12s\t%-9s\t%-4s\t%-4d\t%-9.2lf\t%-9s\t%-7s\n", cur->ID, cur->name, cur->sex, cur->age, cur->score, cur->professional, cur->clas);
			}
			cur = cur->next;
		}
		break;
	}
	case 4:
	{
		printf("请输入需要查找的成绩:");
		double score;
		scanf("%lf", &score);
		InfoSys* cur = pc->next;
		if (cur == NULL)
		{
			printf("未查询到相关信息......\n");
			break;
		}
		printf("                             ~~~~~    学生信息表    ~~~~~\n");
		printf(" ---------------------------------------------------------------------------------------\n");
		printf("%-12s\t%-9s\t%-4s\t%-4s\t%-9s\t%-9s\t%-7s\n", "学号", "姓名", "性别", "年龄", "成绩", "专业", "班级");
		while (cur != NULL)
		{
			if (cur->score == score)
			{
				printf("%-12s\t%-9s\t%-4s\t%-4d\t%-9.2lf\t%-9s\t%-7s\n", cur->ID, cur->name, cur->sex, cur->age, cur->score, cur->professional, cur->clas);
			}
			cur = cur->next;
		}
		break;
	}
	case 5:
	{
		printf("请输入需要查找的专业:");
		char professional[PROFESSIONALNUM] = { 0 };
		scanf("%s", professional);
		InfoSys* cur = pc->next;
		if (cur == NULL)
		{
			printf("未查询到相关信息......\n");
			break;
		}
		printf("                             ~~~~~    学生信息表    ~~~~~\n");
		printf(" ---------------------------------------------------------------------------------------\n");
		printf("%-12s\t%-9s\t%-4s\t%-4s\t%-9s\t%-9s\t%-7s\n", "学号", "姓名", "性别", "年龄", "成绩", "专业", "班级");
		while (cur != NULL)
		{
			if (strcmp(cur->professional, professional) == 0)
			{
				printf("%-12s\t%-9s\t%-4s\t%-4d\t%-9.2lf\t%-9s\t%-7s\n", cur->ID, cur->name, cur->sex, cur->age, cur->score, cur->professional, cur->clas);
			}
			cur = cur->next;
		}
		break;
	}
	case 6:
	{
		printf("请输入需要查找的班级:");
		char clas[CLASNUM] = { 0 };
		scanf("%s", clas);
		InfoSys* cur = pc->next;
		if (cur == NULL)
		{
			printf("未查询到相关信息......\n");
			break;
		}
		printf("                             ~~~~~    学生信息表    ~~~~~\n");
		printf(" ---------------------------------------------------------------------------------------\n");
		printf("%-12s\t%-9s\t%-4s\t%-4s\t%-9s\t%-9s\t%-7s\n", "学号", "姓名", "性别", "年龄", "成绩", "专业", "班级");
		while (cur != NULL)
		{
			if (strcmp(cur->clas, clas) == 0)
			{
				printf("%-12s\t%-9s\t%-4s\t%-4d\t%-9.2lf\t%-9s\t%-7s\n", cur->ID, cur->name, cur->sex, cur->age, cur->score, cur->professional, cur->clas);
			}
			cur = cur->next;
		}
		break;

	}
	default:
		printf("输入错误,正在跳回选择界面......\n");
		Sleep(10);
		break;
	}

}

稍微有点繁琐,可以改进,这里就没有去改进了

另外,查询和分类查询也可以合在一起

6.学生信息的修改

void Modify(InfoSys* pc)
{
	char ID[IDNUM] = { 0 };
	int count = 0;
	InfoSys* cur = pc->next;
	printf("请输入修改学生学号;\n");
	scanf("%s",ID);
	while (cur != NULL)
	{
		if (strcmp(cur->ID, ID) == 0)
		{
			printf("已找到该学生信息......\n");
			count++;
			printf("%-12s\t%-9s\t%-4s\t%-4s\t%-9s\t%-9s\t%-7s\n", "学号", "姓名", "性别", "年龄", "成绩", "专业", "班级");
			printf("%-12s\t%-9s\t%-4s\t%-4d\t%-9.2lf\t%-9s\t%-7s\n", cur->ID, cur->name, cur->sex, cur->age, cur->score, cur->professional, cur->clas);
			break;
		}
		cur = cur->next;
	}
	if (count == 0)
	{
		printf("未找到修改学生信息.....\n");
		return;
	}
	printf("进行修改操作.....\n");
	printf("请依次输入:>  学号 - 姓名 - 性别 - 年龄 - 成绩 - 专业 - 班级\n");
	scanf("%s %s %s %d %lf %s %s", cur->ID, cur->name, cur->sex, &(cur->age), &(cur->score), cur->professional, cur->clas);
	//age是个整数类型,需要&,而其他的是字符串,变量名就是首地址
	Sleep(10);
	printf("修改成功\n");
	return;

}

四、测试结果

1.系统页面以及账号登录与注册

 

 实现掩码

2.选择菜单 

 3.基础功能的实现

在这里就不一个个演示了

全部程序放在下面的链接里了,请自行查看
2022.4.20程序设计项目 · 朱毅峰/zhupiC - 码云 - 开源中国 (gitee.com)https://gitee.com/zhu-pi/zhupi-c/tree/master/2022.4.20%E7%A8%8B%E5%BA%8F%E8%AE%BE%E8%AE%A1%E9%A1%B9%E7%9B%AE


 

  • 11
    点赞
  • 27
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 3
    评论
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

猪皮兄弟

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

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

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

打赏作者

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

抵扣说明:

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

余额充值