管理员:
1.对学生已修学分信息进行管理
2.对学生密码进行查看和修改
3.查询:按学号查询某学生的情况;按班级号查询所有同学;按某种课程,输出未达标要求的学生名单。
学生:
1.查询自己信息,学分
2.对自己的密码进行修改
运用函数,链表,指针及相关知识完成。
1、程序运行
在程序开始运行时,系统自动从后台读取上次已经保存的数据文件,并自动保存在链表中。
2、系统切换
通过用户在登陆界面选择不同的登录方式,根据选择输入个人密码,从而进入不同的菜单(管理员菜单与学生菜单)。特别的,本系统实现了三次密码输入错误自动退出的功能。
3、管理员系统
进入管理员系统,用户可以通过输入对应的数字进入对应功能,包括:
(1)对学生信息的录入、修改、查询、删除
(2)按课程号输出未达标的学生
(3)浏览、统计学生信息
4、学生系统
(1) 查询信息
(2) 修改密码
本系统定义的链表为学生链表:
其成员有:学生姓名,学生密码,学号,班级号,五类课程学分和总学分
4.1 void stupassword
函数功能:确认管理员身份。读取文件,显示登录界面,通过if函数进入不同的密码输入界面;此外若三次密码输入错误,则退出系统。
4.2 void inputstu
函数功能:输入一个学生的信息 ,将学生信息加入已有链表。
4.3 void outputstu
函数功能:打印学生信息,输出链表中学生信息结点的数据。(包括学生姓名,学生密码,学号,班级号,五类课程学分和总学分)
4.4 void deletenode
函数功能:按学号查找并删除学生信息创建新链表,对学生信息进行遍历,找到并进行删除。
4.5 void searchnode1
函数功能:按照学号、班级号查找信息。
4.6 void searchnode2
按班级号查找(按学号大小显示一个班级的情况),输出为整个班级的学生信息。
4.7 void searchnode 3、4
函数功能:输入课程号,按班级号查找(按姓名拼音顺序输出学生信息)。
4.8 void revise
函数功能:按学号查找并修改学生信息
4.9 void allqualifiedstu
函数功能:打印所有可以毕业的学生信息,对所有学生信息进行遍历,判断总学分是否达到要求的200分,并将可以毕业的学生信息打印出来
4.10 void stustatistic
函数功能:按课程号输出未达标的学生。
4.11 void stusave
函数功能:保存文件。
4.12 void stupassword
函数功能: 管理员或学生对密码进行修改。
4.13 void printlist
函数功能:打印链表,输出学生信息。
4.14 void inputg
函数功能:用头插法插入产品信息,若出现重复输入,则返回并重新输入。
4.15 void stupasswordrevise
函数功能:学生修改自己的密码;
追加功能:密码需要两次确认方可修改成功,此目的是防止学生修改密码时误录入错误密码,只需要调用strcmp函数对密码1和密码2进行比较即可。
4.16 void stuview
函数功能:令学生查看信息。
4.17 void keydown1
函数功能:令学生选择操作。
4.18 void readfile
函数功能:从文件中读取信息。
4.19 void writefile
函数功能:从链表中读取文件,写进文本.txt里。
#define _CRT_SECURE_NO_WARNINGS
#include
#include
#include
struct student
{
char name[20];
char password[20];//学生密码(学生可以修改)
int num;//学号
int classnum;//班级号
int credit[5], allcredit;//五类课程学分和总学分
struct student* next;
};
//管理员操作
void menu1();//学生菜单
void menu2();//管理员菜单
void keydown1(int num);//学生选择操作
void keydown2(struct student* list);//管理员选择操作
int Confirm1(int num);//确认学生身份
int Confirm2();//确认管理员身份
void inputstu(struct student* stu); //输入一个学生的信息
void outputstu(struct student* stu); //输出一个学生的信息
struct student* createlist();//创建链表
void insertnode(struct student* headnode, struct student* data);//插入节点(头插法)
void deletenode(struct student* headnode, int num);//按学号查找并删除节点
void searchnode1(struct student* headnode, int num);//按学号查找结点
void searchnode2(struct student* headnode, int classnum);//按班级号查找(按学号大小显示一个班级的情况)
void searchnode3(struct student* headnode, int classnum);//按班级号查找(按姓名拼音顺序输出学生信息)
void searchnode4(struct student* headnode, int subnum);//输入课程号,输出未达标学生信息
void revise(struct student* headnode, int num);//按学号查找并修改学生信息0
void allqualifiedstu(struct student* headnode);//打印所有可以毕业的学生信息
void printlist(struct student* headnode);//打印链表
void readfile(char* filename);//从文件中读取信息
void writefile(struct student* headnode, char* filename);//从链表中读取文件,写进文本1.txt里
void save(char* filename);//将信息保存到最终的文件stu.txt里
void stustatistic(struct student* headnode);//统计功能(输入学号,输出该学生的课程总学分;输入班级号,输出达标人数和没有达标的学生人数及其信息)
void stupasswordmanage(struct student* headnode);//查看学生密码
//学生操作
void stuview(int num);//学生查看信息
void stupasswordrevise(int num);//学生修改密码
int main()
{
int c,num;
struct student* list = createlist();
struct student* stu = (struct student*)malloc(sizeof(struct student));
printf("请问您是学生还是管理员:\n");
printf("1.学生 2.管理员\n");
scanf_s("%d", &c);
if (c == 1)
{
printf("请输入您的学号:\n");
scanf_s("%d", &num);
if (Confirm1(num)==1) {//确认学生身份
while (1) {
menu1();
keydown1(num);
system("pause");//暂停程序,等待任意键继续操作
}
}
}
else if (c == 2) {
if (Confirm2() == 1) {//管理员密码正确
while (1) {
menu2();
keydown2(list);
system("pause");//暂停程序,等待任意键继续操作
}
}
}
else {
printf("选择错误,请重新输入!\n");
}
return 0;
}
int Confirm1(int num)//确认学生身份
{
FILE* fp = fopen("stu.txt", "r");//以只读方式打开文件
int n=0;
struct student a;
char key[100];
printf("请输入您的密码:\n");
scanf_s("%s", key , sizeof(key));
if (fp == NULL)
{
printf("文件无法打开!\n");
exit(1);//异常退出
}
else {//在文件中查找该学生
while (!feof(fp))
{
fscanf(fp, "%d\t%s\t%d\t%d\t%d\t%d\t%d\t%d\t%d\t%s\n", &a.num, a.name, &a.classnum, &a.credit[0], &a.credit[1], &a.credit[2], &a.credit[3], &a.credit[4], &a.allcredit, a.password);
if (a.num == num)
{
n = 1;
if (strcmp(a.password, key) == 0) {
printf("登陆成功!\n");
return 1;
}
else {
printf("密码错误,您还有两次机会!请重新输入:\n");
scanf_s("%s", key, sizeof(key));
if (strcmp(a.password, key) == 0) {
printf("登陆成功!\n");
return 1;
}
else {
printf("密码错误,您还有一次机会!请重新输入:\n");
scanf_s("%s", key, sizeof(key));
if (strcmp(a.password, key) == 0) {
printf("登陆成功!\n");
return 1;
}
else {
printf("对不起,您无权限操作!\n");
return 0;
}
}
}
}
}
if (n == 0) {
printf("对不起,此学生不存在!\n");
return 0;
}
}
}
int Confirm2()//确认管理员身份
{
char key[100] = { "okk" };
char a[100];
printf("请输入管理员密码:\n");
scanf_s("%s", a, sizeof(a));
if (strcmp(a, key) == 0) {
return 1;
}
else {
printf("密码错误,您还有两次机会!请重新输入:\n");
scanf_s("%s", a, sizeof(a));
if (strcmp(a, key) == 0) {
return 1;
}
else {
printf("密码错误,您还有一次机会!请重新输入:\n");
scanf_s("%s", a, sizeof(a));
if (strcmp(a, key) == 0) {
return 1;
}
else {
return 0;
}
}
}
}
void inputstu(struct student* stu) //输入一个学生的信息
{
int k = 0;
scanf_s("%d", &stu->num);
scanf_s("%s", stu->name, sizeof(stu->name));//scanf_s函数输入字符串的时候需要特别注意一下
scanf_s("%d", &stu->classnum);
for (int i = 0; i < 5; i++) {
scanf_s("%d", &stu->credit[i]);
k += stu->credit[i];
}
scanf_s("%s", stu->password, sizeof(stu->password));
stu->allcredit = k;
}
void outputstu(struct student* stu) //输出一个学生的信息
{
struct student* pmove = stu;
printf("%d\t%s\t%d\t", pmove->num, pmove->name, pmove->classnum);//学号、姓名、班级号
for (int i = 0; i < 5; i++) {
printf("%d\t", pmove->credit[i]);
}
printf("%d\n", pmove->allcredit);
}
struct student* createlist()//创建链表
{
struct student* headnode = (struct student*)malloc(sizeof(struct student));//结构体变量表示表头,动态内存申请
//headnode = NULL;//headnode没有做初始化,作为表头,所以下面打印的时候从next开始打印
headnode->next = NULL;
return headnode;
}
void insertnode(struct student* headnode, struct student* data)//插入节点(头插法)
{
struct student* newnode = (struct student*)malloc(sizeof(struct student));
newnode = data;
newnode->next = headnode->next;
headnode->next = newnode;
}
void deletenode(struct student* headnode, int num)//按学号查找并删除节点
{
struct student* posnode = headnode->next;
struct student* posfrontnode = headnode;
if (posnode == NULL)
{
printf("数据为空,无法删除!\n");
return;
}
while (posnode != NULL) {
if (posnode->num == num) {
posfrontnode->next = posnode->next;//找到了,开始删除
free(posnode);
return;
}
else {
posfrontnode = posnode;
posnode = posnode->next;
}
}
printf("该同学不存在,无法删除!\n");
return;
}
void searchnode1(struct student* headnode, int num)//按学号查找学生信息
{
struct student* pmove = headnode->next;
if (pmove == NULL) {
printf("文件为空,无法查找!\n");
return;
}
while (pmove != NULL) {
if (pmove->num == num) {
outputstu(pmove);
return;
}
else
pmove = pmove->next;
}
printf("查找不到该同学!\n");
return;
}
void searchnode2(struct student* headnode, int classnum)//按班级号查找(按学号大小显示一个班级的情况)
{
struct student* stu[100];//一个班级最多100人
int i = 0, t = 0;
struct student* pmove = headnode->next;
struct student* pnew = (struct student*)malloc(sizeof(struct student));
if (pmove == NULL) {
printf("文件为空,无法查找!\n");
return;
}
while (pmove) {
if (pmove->classnum == classnum) {
stu[i] = (struct student*)malloc(sizeof(struct student));
stu[i] = pmove;
i++;
}
pmove = pmove->next;
}
if (i == 0) {
printf("不存在该班级!\n");
return;
}
else {//如果班级号存在,对同学学号进行升序排序
for (int k = 0; k < i - 1; k++) {
for (int j = 0; j < i - 1 - k; j++) {
if (stu[j]->num > stu[j + 1]->num) {
pnew = stu[j];
stu[j] = stu[j + 1];
stu[j + 1] = pnew;
}
}
}
printf("学号\t姓名\t班级号\t基础类课程\t专业基础类课程\t专业类课程\t专业选修课程\t实践课程\t总学分\n");
for (int k = 0; k < i; k++) {
outputstu(stu[k]);
}
}
}
void searchnode3(struct student* headnode, int classnum)//按班级号查找(按姓名拼音顺序输出学生信息)
{
struct student* stu[100];//一个班级最多100人
int i = 0, t = 0;
struct student* pmove = headnode->next;
struct student* pnew;
if (pmove == NULL) {
printf("文件为空,无法查找!\n");
return;
}
while (pmove != NULL) {
if (pmove->classnum == classnum) {
stu[i] = (struct student*)malloc(sizeof(struct student));
stu[i] = pmove;
i++;
}
pmove = pmove->next;
}
if (i == 0) {
printf("不存在该班级同学!\n");
return;
}
else {//如果班级号存在,对姓名拼音大小进行升序排序
for (int k = 0; k < i - 1; k++) {
for (int j = 0; j < i - 1 - k; j++) {
if (strcmp(stu[j]->name, stu[j + 1]->name) > 0) {
pnew = stu[j];
stu[j] = stu[j + 1];
stu[j + 1] = pnew;
}
}
}
printf("学号\t姓名\t班级号\t基础类课程\t专业基础类课程\t专业类课程\t专业选修课程\t实践课程\t总学分\n");
for (int k = 0; k < i; k++) {
outputstu(stu[k]);
}
}
}
void searchnode4(struct student* headnode, int subnum)//输入课程号,输出未达标学生信息
{
struct student* pmove = headnode->next;
switch (subnum)
{
case 0:while (pmove) {
if (pmove->credit[0] < 50) {
outputstu(pmove);
}
pmove = pmove->next;
}
break;
case 1:
while (pmove) {
if (pmove->credit[1] < 50) {
outputstu(pmove);
}
pmove = pmove->next;
}
break;
case 2:
while (pmove) {
if (pmove->credit[2] < 36) {
outputstu(pmove);
}
pmove = pmove->next;
}
break;
case 3:
while (pmove) {
if (pmove->credit[3] < 24) {
outputstu(pmove);
}
pmove = pmove->next;
}
break;
case 4:
while (pmove) {
if (pmove->credit[4] < 40) {
outputstu(pmove);
}
pmove = pmove->next;
}
break;
default:
printf("该课程号不存在!\n");
break;
}
}
void revise(struct student* headnode, int num)//按学号查找并修改学生信息
{
struct student* pmove = headnode->next;
if (pmove == NULL) {
printf("文件为空,无法修改!\n");
return;
}
while (pmove != NULL) {
if (pmove->num == num) {
int allcredit = 0;
printf("%d\t%s\t%d\t", pmove->num, pmove->name, pmove->classnum);//学号、姓名、班级号
for (int i = 0; i < 5; i++) {
printf("%d\t", pmove->credit[i]);
allcredit += pmove->credit[i] / 5;
}
printf("\n");
printf("请输入您要修改的信息:\n");
inputstu(pmove);
return;
}
else
pmove = pmove->next;
}
printf("查找不到该同学,无法修改!\n");
return;
}
void printlist(struct student* headnode)//打印链表
{
struct student* pmove = headnode->next;
if (pmove == NULL) {
printf("文件为空!\n");
}
else {
printf("学号\t姓名\t班级号\t基础类课程\t专业基础类课程\t专业类课程\t专业选修课程\t实践课程\t总学分\n");
while (pmove) {
outputstu(pmove);
pmove = pmove->next;
}
}
}
void allqualifiedstu(struct student* headnode)//打印所有可以毕业的学生信息
{
int k = 0;
struct student* pmove = headnode->next;
while (pmove) {
if (pmove->allcredit == 200) {
outputstu(pmove);
k++;
}
pmove = pmove->next;
}
if (k == 0) {
printf("暂时没有符合毕业条件的学生,您可以提醒他们修补学分喔!\n");
}
}
void stustatistic(struct student* headnode)
{
int num, k = 0;
int i = 0, t = 0;
int classnum;
struct student* pnew;
struct student* pmove;
struct student* stu[100];//一个班级最多100人
pmove = headnode->next;
int n = 0;
while (1)
{
printf(" 请选择:\n");
printf(" 1.查找学生的课程总学分\n");
printf(" 2.查找班级达标情况\n");
printf(" 请输入您的选项:\n");
scanf_s("%d", &n);
if (n == 1 || n == 2)
{
break;
}
else
printf("输入错误,请重新输入哦\n");
}
if (n == 1)
{
printf("请输入要查找学生的学号:\n");
scanf_s("%d", &num);
while (pmove->num != num && pmove->next != NULL)
{
headnode = pmove;
pmove = pmove->next;
}
if (pmove->num == num)
{
printf("%d", pmove->allcredit);
}
else
printf("未查找到该学生,请检查是否输入错误\n");
}
if (n == 2)
{
printf("请输入要查找的班级:\n");
scanf_s("%d", &classnum);
if (pmove == NULL) {
printf("文件为空,无法查找!\n");
return;
}
while (pmove != NULL) {
if (pmove->classnum == classnum) {
stu[i] = (struct student*)malloc(sizeof(struct student));
stu[i] = pmove;
i++;
}
pmove = pmove->next;
}
if (i == 0) {
printf("不存在该班级同学!\n");
return;
}
else {//如果班级号存在,对姓名拼音大小进行升序排序
for (int k = 0; k < i - 1; k++) {
for (int j = 0; j < i - 1 - k; j++) {
if (strcmp(stu[j]->name, stu[j + 1]->name) > 0) {
pnew = stu[j];
stu[j] = stu[j + 1];
stu[j + 1] = pnew;
}
}
}
for (int k = 0; k < i; k++) {
if (stu[k]->allcredit >= 200)
{
t++;
outputstu(stu[k]);
}
}
printf("达标人数:%d\n", t);
printf("未达标人数:%d\n", i - t);
for (int k = 0; k < i; k++)
{
if (stu[k]->allcredit < 200)
{
outputstu(stu[k]);
}
else
printf("未找到该班级,请检查是否输入错误\n");
}
}
}
}
void stupasswordmanage(struct student* headnode)//管理员查看学生密码
{
int num,n=0;
struct student* pmove = headnode->next;
printf("请输入您要查看的学生学号:\n");
scanf_s("%d", &num);
if (pmove == NULL) {
printf("文件为空!\n");
return;
}
while (pmove) {
if (pmove->num == num) {
printf("%s\n", pmove->password);
n = 1;
return;
}
pmove = pmove->next;
}
if (n == 0) {
printf("此学号不存在!\n");
}
}
void stupasswordrevise(int num)//学生修改自己的密码
{
int n = 0;
char key;
struct student a;
FILE* fp = fopen("stu.txt", "r");//以只读方式打开文件
FILE* fpw = fopen("2.txt", "w");//临时文件,每次都刷新2.txt里面的内容,然后把stu里面的信息复制到2.txt里面,最后把2.txt重命名为stu.txt
char newpassword1[20];
char newpassword2[20];
if (fp == NULL)
{
printf("文件无法打开!\n");
exit(1);//异常退出
}
else {//在文件中查找该学生
while (!feof(fp))
{
fscanf(fp, "%d\t%s\t%d\t%d\t%d\t%d\t%d\t%d\t%d\t%s\n", &a.num, a.name, &a.classnum, &a.credit[0], &a.credit[1], &a.credit[2], &a.credit[3], &a.credit[4], &a.allcredit, a.password);
if (a.num == num)
{
n = 1;
printf("请输入您的新密码:\n");
scanf_s("%s", newpassword1, 20);
printf("再次输入你的密码\n");
scanf_s("%s", newpassword2, 20);
if (strcmp(newpassword1, newpassword2) == 0)
{
strcpy(a.password, newpassword1);
fprintf(fpw, "%d\t%s\t%d\t%d\t%d\t%d\t%d\t%d\t%d\t%s\n", a.num, a.name, a.classnum, a.credit[0], a.credit[1], a.credit[2], a.credit[3], a.credit[4], a.allcredit, a.password);
printf("修改成功!\n");
}
else {
printf("两次输入密码不一致,请重新输入!\n");
}
}
else {
fprintf(fpw, "%d\t%s\t%d\t%d\t%d\t%d\t%d\t%d\t%d\t%s\n", a.num, a.name, a.classnum, a.credit[0], a.credit[1], a.credit[2], a.credit[3], a.credit[4], a.allcredit, a.password);
}
}
if (n == 0) {
printf("对不起,此学生不存在!\n");
}
}
fclose(fp);
fclose(fpw);
system("del stu.txt");
system("rename 2.txt stu.txt");//将文件2重命名为stu文件
}
void stuview(int num)//学生查看信息
{
struct student a;
int n = 0;
FILE* fp;
fp = fopen("stu.txt", "r");//以只读方式打开文件
if (fp == NULL)
{
printf("文件无法打开!\n");
exit(1);//异常退出
}
else {
while (!feof(fp))
{
fscanf(fp, "%d\t%s\t%d\t%d\t%d\t%d\t%d\t%d\t%d\t%s\n", &a.num, a.name, &a.classnum, &a.credit[0], &a.credit[1], &a.credit[2], &a.credit[3], &a.credit[4], &a.allcredit, a.password);
if (a.num == num)
{
n = 1;
outputstu(&a);
fclose(fp);
return;
}
}
if(n==0)
printf("对不起,查找不到此学生!\n");
}
}
void menu1()//学生菜单
{
printf("-------------------------------【学分信息系统】--------------------------------------\n");
printf("\n");
printf(" 0.查看学分信息 \n");
printf(" 1.修改学生密码 \n");
printf(" 2.退出学生系统 \n");
printf("-------------------------------------------------------------------------------------\n");
}
void menu2()
{
//所有操作都同步到文件
printf("---------------------------------【学分信息管理系统】-------------------------------------\n");
printf("\n");
printf(" 0.录入学生信息 \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(" 9.浏览全部学生信息 \n");
printf(" 10.统计学生信息 \n");
printf(" 11.密码管理 \n");
printf(" 12.退出系统 \n");
printf(" 13.保存文件 \n");
printf("------------------------------------------------------------------------------------------\n");
}
void keydown1(int num)//学生选择操作
{
int choice;
scanf_s("%d", &choice);
switch (choice)
{
case 0:printf("--------------------------------------【查看学分信息】--------------------------------------\n");
printf("姓名\t学号\t班级号\t基础类课程\t专业基础类课程\t专业类课程\t专业选修课程\t实践课程\t总学分\n");
stuview(num);
break;
case 1:printf("--------------------------------------【修改学生密码】--------------------------------------\n");
stupasswordrevise(num);
break;
case 2:printf("--------------------------------------【退出学生系统】--------------------------------------\n");
printf("正常退出!\n");
system("pause");
exit(0);
break;
default:
printf("输入错误!\n");
break;
}
}
void keydown2(struct student* list)
{
int num, classnum, subnum;
struct student* stu = (struct student*)malloc(sizeof(struct student));
int choice;
scanf_s("%d", &choice);
switch (choice)
{
case 0:
printf("--------------------------------------【录入学生信息】--------------------------------------\n");
printf("请输入学生学号、姓名、班级号、基础类课程学分、专业基础类课程学分、专业类课程学分、专业选修学分、实践类课程学分、学生密码:\n");
fflush(stdin);//清空缓冲区
inputstu(stu);
insertnode(list, stu);
break;
case 1:
printf("--------------------------------------【修改学生信息】--------------------------------------\n");
printf("请输入您需要修改的学生学号:\n");
scanf_s("%d", &num);
revise(list, num);//按学号查找并修改学生信息
break;
case 2:
printf("--------------------------------------【删除学生信息】--------------------------------------\n");
printf("请输入您需要删除的学生学号:\n");
scanf_s("%d", &num);
deletenode(list, num);
break;
case 3:
printf("--------------------------------------【按学号查询学生信息】--------------------------------------\n");
printf("请输入你要查找的学号:\n");
scanf_s("%d", &num);
searchnode1(list, num);//按学号查找结点
break;
case 4:
printf("--------------------------------------【输入班级号,按照学号顺序输出学生信息】--------------------------------------\n");
printf("请输入你要查找的班级号:\n");
scanf_s("%d", &classnum);
searchnode2(list, classnum);//按班级号查找(按学号大小显示一个班级的情况)
break;
case 5:
printf("--------------------------------------【输入班级号,按照拼音顺序顺序输出学生信息】--------------------------------------\n");
printf("请输入你要查找的班级号:\n");
scanf_s("%d", &classnum);
searchnode3(list, classnum);//按班级号查找(按姓名拼音顺序输出学生信息)
break;
case 6:
printf("--------------------------------------【输入课程号,输出未达标学生信息】--------------------------------------\n");
printf("请输入您要查询的课程号:\n");
scanf_s("%d", &subnum);
searchnode4(list, subnum);//输入课程号,输出未达标学生信息
break;
case 7:
printf("--------------------------------------【查询满足毕业条件的学生信息】--------------------------------------\n");
allqualifiedstu(list);//打印所有可以毕业的学生信息
break;
case 8:
printf("--------------------------------------【浏览本次学生信息】--------------------------------------\n");
printlist(list);
break;
case 9:
printf("--------------------------------------【浏览全部学生信息】--------------------------------------\n");
readfile("stu.txt");
break;
case 10:
printf("--------------------------------------【统计学生信息】--------------------------------------\n");
stustatistic(list);
break;
case 11:
printf("--------------------------------------【密码管理】--------------------------------------\n");
stupasswordmanage(list);
break;
case 12:
printf("--------------------------------------【退出系统】--------------------------------------\n");
printf("正常退出!\n");
system("pause");
exit(0);
break;
case 13:
printf("--------------------------------------【保存文件】--------------------------------------\n");
save("1.txt");//将以上操作保存到最终的学生文件里面
break;
default:
printf("选择错误!请重新输入\n");
system("pause");
break;
}
writefile(list, "1.txt");
}
void readfile(char *filename)//从文件中读取信息并显示出来
{
struct student a;
FILE* fp;
fp = fopen("stu.txt", "r");//以只读方式打开文件
if (fp == NULL)
{
printf("文件无法打开!\n");
exit(1);//异常退出
}
else {
while (!feof(fp))
{
fscanf(fp, "%d\t%s\t%d\t%d\t%d\t%d\t%d\t%d\t%d\t%s\n", &a.num, a.name, &a.classnum, &a.credit[0], &a.credit[1], &a.credit[2], &a.credit[3], &a.credit[4], &a.allcredit, a.password);
outputstu(&a);
}
}
fclose(fp);
}
void save(char* filename)//将信息保存到最终的文件stu.txt里
{
struct student a;
FILE* fp = fopen(filename, "r");//以只读的方式打开文件
FILE* fpw = fopen("stu.txt", "a+");//以追加的方式打开文件,将数据追加到文件末尾
if (fp == NULL)
{
printf("文件无法打开!\n");
exit(1);//异常退出
}
else {
while (!feof(fp))
{
fscanf(fp, "%d\t%s\t%d\t%d\t%d\t%d\t%d\t%d\t%d\t%s\n", &a.num, a.name, &a.classnum, &a.credit[0], &a.credit[1], &a.credit[2], &a.credit[3], &a.credit[4], &a.allcredit, a.password);
fprintf(fpw, "%d\t%s\t%d\t%d\t%d\t%d\t%d\t%d\t%d\t%s\n", a.num, a.name, a.classnum, a.credit[0], a.credit[1], a.credit[2], a.credit[3], a.credit[4], a.allcredit, a.password);
}
}
fclose(fp);
fclose(fpw);
}
void writefile(struct student* headnode, char* filename)//从链表中读取文件,追加进文本.txt里
{
FILE* fp;
fp = fopen(filename, "w");
if (fp == NULL) {
printf("文件打开失败!\n");
}
struct student* pmove = headnode->next;
while (pmove) {
fprintf(fp, "%d\t%s\t%d\t%d\t%d\t%d\t%d\t%d\t%d\t%s\n", pmove->num, pmove->name, pmove->classnum, pmove->credit[0], pmove->credit[1], pmove->credit[2], pmove->credit[3], pmove->credit[4], pmove->allcredit, pmove->password);
pmove = pmove->next;
}
fclose(fp);
}
学分管理系统主要分为两个部分,一部分是学生,一部分是管理员。要实现管理员的操作功能主要通过链表实现,管理员每次对链表进行操作都同步到文件,所以只需要知道一个链表的表头就能实现对链表的增删改查等功能;要实现学生功能主要是对文件本身直接操作,结合实际,我认为学生只有两个操作权限,一是查看自己的信息,二是修改自己的密码,学生修改密码时需要对文件本身进行操作。
1、学生信息的录入、修改、删除、查找其实都是对链表进行操作,设置一个表头和结构体指针,遍历链表,分别实现相应功能,这部分内容较为简单,没有遇到大的问题。
2、查询学生信息主要分为四个功能,为了使程序看起来简洁,我分为四个小函数写,其中输入班级号按照学号顺序输出学生信息主要用到冒泡排序,姓名拼音顺序直接调用strcmp函数和冒泡排序即可。
3、学生自行修改密码,主要是对文件本身进行操作,由于对文件操作不熟悉,这部分内容我写了很久,调试过很多次,最后选择以创建新文件的形式完成密码的修改及信息保存——即打开一个文件,对其进行读取,当读取到目标结构体时,对其进行修改,修改后将其写入另一个新建的文本,如果没有进行修改,则直接将原文本的结构体内容写入新文本,最后删除原文本,并对新文本重命名即可。
这次程序设计实践主要让我对链表和结构体的运用更加熟练,最重要的是我学会了操作文件。其实静下心来先把课本上关于文件的基础知识过一遍,文件操作的内容并不难,所以静下心来学习很重要,一味赶进度效率低而且容易导致心情烦躁。
这次实践感触最深的是没有早点开始写大作业,导致在期末复习周带着焦虑的心情写代码。通过这次实践,我想我以后会更加注重小组成员之间的交流与合作,也会学着规划自己的时间,不再将任务都留到ddl,学着更加合理地为组员安排任务…总之,这次程序实践,收获很大,既有学习能力上的,也有思维上的。