登录/注册
定义一个账号与密码的结构体,再定义一个全局变量用作头节点(哑结点)。
typedef struct accounts {
char Number[50];
char Password[50];
struct accounts* next;
}node2;
node2* accounthead = (node2*)malloc(sizeof(node2));
菜鸡为了简便操作,将学生账号与学号绑定一起,格式为0X0XX。第一个X代表班级,后两个X代表班内序号,这比较容易理解。教师账号我定义为1X00X,第一个X代表班级,最后一位X:1代表是数学教师,2代表是英语教师,3代表是计算机教师。这样一来,学生与教师可以通过首位0或1区别。教师在修改成绩时也就可以分开来,教师不能修改非自己所教学科的成绩。
登录时密码的处理也比较有意思,还好菜鸡在以前了解过这个问题,还发过博客😁。简单密码问题 这次为了方便使用,菜鸡把它放进了函数中:
void inputpassword(char* password) {
int i;
for (i = 0; i < 49; ) {
char A;
A = _getch();
if (A != '\r') {
if (A == 8) {
if (i > 0) {
putchar('\b \b');
password[--i] = 0;
}
} else {
password[i++] = A;
putchar('*');
password[i] = 0;
}
} else {
break;
}
}
password[++i] = 0;
}
菜鸡的思路是,如果一个人登录,他的账号不存在,但他这个人存在(学号/教师号存在),即当场把他拉去注册。下面用学生注册为大家举例:
void student_login() {
char a[50] = { 0 };
gets_s(a);
while (strlen(a) != 5 || a[0] != '0') {
//账号长度为5,学生首位应为0
printf(" 格式错误,请重新输入!!!\n "); Sleep(1000);
login_page_display();
gets_s(a);
}
creat_account();
//这个函数用来把所有账号密码放进链表,以便遍历并判断账号是否存在
int flag = 0;
node2* t = accounthead;
while (t->next) {
t = t->next;
if (strcmp(t->Number, a) == 0) {
flag = 1;
break;
}
}
//存在flag为1,否则为0
if (flag == 0) {
system("cls");
printf("\n\n\n\n 账户未注册,请先注册,正在跳转");
Sleep(500); printf("。"); Sleep(500); printf("。"); Sleep(500); printf("。"); Sleep(500);
student_register(a);
//账号未注册,先去注册,人是否存在在注册函数判断。
} else {
printf(" 请输入密码:\n ");
char CorrectPassword[50], CurPassword[50] = { 0 };
strcpy(CorrectPassword, t->Password);
inputpassword(CurPassword);
while (strcmp(CorrectPassword, CurPassword)) {
login_page_display();
puts(a);
printf(" 密码错误!!!请重新输入:\n ");
inputpassword(CurPassword);
}
printf("\n 密码正确,正在跳转");
Sleep(500); printf("。"); Sleep(500); printf("。"); Sleep(500); printf("。"); Sleep(500);
student_main_page(a);
//密码正确,进入学生主页
}
}
学生进入直接注册的思路与此相似,菜鸡非常懒惰且贪玩(写的臭且麻烦),不想多说了🤪。
学生注册函数:
void student_register(char* a) {
node* P = (node*)malloc(sizeof(node));
node2* p2;
P = Creat_all_student();
int flag = 0;
node* p = P;
while (p->next) {
p = p->next;
if (!strcmp(p->Number, a)) {
flag = 1;
break;
}
}
p2 = accounthead;
if (flag) {
student_register_2(a, p2);
student_main_page(a);
} else {
printf("\n 学号不存在!!!");
Sleep(1000);
menu();
}
}
这里通过一个函数举例来为大家介绍一下如何把文件读入链表:
void creat_account() {
char Number1[50] = { 0 };
char Password1[50] = { 0 };
FILE* FP;
FP = fopen("C:\\Users\\51098\\Desktop\\iOS\\Accounts.txt", "rb");
//以读的方式打开文件
if (FP == NULL) {
printf("无法打开文件\n");
exit(0);//终止程序
}
node2* p = accounthead;
while (!feof(FP)) {
fscanf(FP, "%s %s ", Number1, Password1);
//读入文件内容
node2* pnew = (node2*)malloc(sizeof(node2));
strcpy(pnew->Number, Number1);
strcpy(pnew->Password, Password1);
p->next = pnew;
pnew->next = NULL;
p = pnew;
}
fclose(FP);
}
程序的很多内容十分相似,菜鸡非常懒惰且贪玩(写的臭且麻烦),不再多说了😶。
接下来给大家展示一下我这复杂(臭且恶心)的链表排序。这次写学生管理系统时菜鸡只写到了有关学生的排序内容,这个排序有两个,从小至大与从大至小。可以按班内学号排,按总分排,按数学排等等。下面给出代码:
node* SortList_big_to_small(node* Head, int n) {
if (Head->next == NULL || Head->next->next == NULL) {
return Head;
}
node* last = Head->next, * cur = last->next;
int Curval = 0, Lastval = 0;
if (n == 1) {//按学号排
Curval = (cur->Number[3] - '0') * 10 + (cur->Number[4] - '0');
Lastval = (last->Number[3] - '0') * 10 + (last->Number[4] - '0');
} else if (n == 2) {//按总成绩排
Curval = cur->math + cur->english + cur->computer;
Lastval = last->math + last->english + last->computer;
} else if (n == 3) {
Curval = cur->math;
Lastval = last->math;
} else if (n == 4) {
Curval = cur->english;
Lastval = last->english;
} else if (n == 5) {
Curval = cur->computer;
Lastval = last->computer;
}
while (cur) {
if (n == 1) {//按学号排
Curval = (cur->Number[3] - '0') * 10 + (cur->Number[4] - '0');
Lastval = (last->Number[3] - '0') * 10 + (last->Number[4] - '0');
} else if (n == 2) {//按总成绩排
Curval = cur->math + cur->english + cur->computer;
Lastval = last->math + last->english + last->computer;
} else if (n == 3) {
Curval = cur->math;
Lastval = last->math;
} else if (n == 4) {
Curval = cur->english;
Lastval = last->english;
} else if (n == 5) {
Curval = cur->computer;
Lastval = last->computer;
}
if (Lastval >= Curval) {
last = cur;
if (n == 1) {//按学号排
Curval = (cur->Number[3] - '0') * 10 + (cur->Number[4] - '0');
Lastval = (last->Number[3] - '0') * 10 + (last->Number[4] - '0');
} else if (n == 2) {//按总成绩排
Curval = cur->math + cur->english + cur->computer;
Lastval = last->math + last->english + last->computer;
} else if (n == 3) {
Curval = cur->math;
Lastval = last->math;
} else if (n == 4) {
Curval = cur->english;
Lastval = last->english;
} else if (n == 5) {
Curval = cur->computer;
Lastval = last->computer;
}
} else {
int Nextval;
node* i = Head;
if (n == 1) {//按学号排
Nextval = (i->next->Number[3] - '0') * 10 + (i->next->Number[4] - '0');
} else if (n == 2) {//按总成绩排
Nextval = i->next->math + i->next->english + i->next->computer;
} else if (n == 3) {
Nextval = i->next->math;
}
else if (n == 4) {
Nextval = i->next->english;
} else if (n == 5) {
Nextval = i->next->computer;
}
while (i->next && Nextval >= Curval) {
i = i->next;
if (n == 1) {//按学号排
Nextval = (i->next->Number[3] - '0') * 10 + (i->next->Number[4] - '0');
Curval = (cur->Number[3] - '0') * 10 + (cur->Number[4] - '0');
} else if (n == 2) {//按总成绩排
Nextval = i->next->math + i->next->english + i->next->computer;
Curval = cur->math + cur->english + cur->computer;
} else if (n == 3) {
Nextval = i->next->math;
Curval = cur->math;
} else if (n == 4) {
Nextval = i->next->english;
Curval = cur->english;
} else if (n == 5) {
Nextval = i->next->computer;
Curval = cur->computer;
}
}
last->next = cur->next;
cur->next = i->next;
i->next = cur;
if (n == 1) {//按学号排
Nextval = (i->next->Number[3] - '0') * 10 + (i->next->Number[4] - '0');
Curval = (cur->Number[3] - '0') * 10 + (cur->Number[4] - '0');
} else if (n == 2) {//按总成绩排
Nextval = i->next->math + i->next->english + i->next->computer;
Curval = cur->math + cur->english + cur->computer;
} else if (n == 3) {
Nextval = i->next->math;
Curval = cur->math;
} else if (n == 4) {
Nextval = i->next->english;
Curval = cur->english;
} else if (n == 5) {
Nextval = i->next->computer;
Curval = cur->computer;
}
}
cur = last->next;
}
return Head;
}
这个排序的思路是插入排序,里面的if与else大家也很容易看出只是为了迎合不同的需要而做的操作,没屁用。大家可以自行把那些东西忽略来看程序的精华。
在把链表的内容读入后我们就可以对链表的内容进行操作了,增删查改,排序。。。但是,我们仅在程序中对链表进行了改动,文件内容并没有发生变化,所以我们需要将链表的内容保存到文件中。
下面用一个保存的函数为大家举例:
void Save(int n) {
node* p = NULL;
FILE* fp;
char route[100];
if (n == 1) {
strcpy(route, "C:\\Users\\51098\\Desktop\\iOS\\class1.txt"); p = head1;
} else if (n == 2) {
strcpy(route, "C:\\Users\\51098\\Desktop\\iOS\\class2.txt"); p = head2;
} else if (n == 3) {
strcpy(route, "C:\\Users\\51098\\Desktop\\iOS\\class3.txt"); p = head3;
} else if (n == 4) {
strcpy(route, "C:\\Users\\51098\\Desktop\\iOS\\class4.txt"); p = head4;
} else if (n == 5) {
strcpy(route, "C:\\Users\\51098\\Desktop\\iOS\\class5.txt"); p = head5;
}
if ((fp = fopen(route, "wb")) == NULL) {
exit(1);
}
for (p = p->next; p != NULL; p = p->next) {
fprintf(fp, "%s %s %s %d %d %d \n", p->Name, p->Number, p->Class, p->math, p->english, p->computer);
}
fclose(fp);
}
最后,菜鸡为大家介绍一下菜鸡的成绩申诉。
菜鸡把学生的成绩申诉与教师的成绩更新提醒放入一个文件中,管理员可以分情况看到学生的申诉与教师的成绩更新提醒。在手动输入学生成绩时自动把本班的三科教师的提醒删去,在教师端更改学生信息时把该学生的申诉信息删去。
以上就是本次博客的全部主要内容啦!