#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#include<conio.h>
FILE *stud;
FILE *tempx;
enum operation
{
key_1 = '1',
key_2 = '2',
key_3 = '3',
key_4 = '4',
key_5 = '5',
key_6 = '6',
key_7 = '7',
key_ESC = 27
};
FILE *password;
FILE *pstemp;
typedef struct Psward
{
char Account[16];
char PsWord[16];
struct Psward* pnext;
}Ps;
typedef struct student
{
int num;
int age;
char sex[4];
char class[32];
char location[32];
char name[32];
struct student* pfront;
struct student* pnext;
} stu;
char* RegisterAccount(Ps const * phead)//账号规则
{
static char Account[16];
puts("注册账号,必须为数字且不能大于15位");
nu:
scanf("%s", Account);
if (strlen(Account) < 5)
{
puts("账号太短,请重新输入!");
fflush(stdin);
goto nu;
}
for (unsigned int i = 0; i<strlen(Account); ++i)
{
if (Account[i] < 48 || Account[i] > 57)
{
puts("账号必须全是数字,请重新输入!");
fflush(stdin);
goto nu;//存在不是数字的玩意儿
}
}
while (phead)
{
if (!strcmp(phead->Account, Account))
{
puts("账户已存在!请重新输入");
fflush(stdin);
goto nu;
}
phead = phead->pnext;
}
return Account;
}
void TraversereMove2(Ps* const phead)
{
Ps *pthis = phead;
pstemp = fopen("./临时文件.txt", "a+");
while (pthis)
{
fprintf(pstemp, "%s %s", pthis->Account, pthis->PsWord);
pthis = pthis->pnext;
}
fclose(pstemp);
remove("账号密码.txt");
rename("临时文件.txt", "账号密码.txt");
}
char *PsWord()//密码规则
{
static char PsWd1[16];
char PsWd2[16];
char p = 'T';
puts("请输入你的密码,以字母与数字的组合且必须以字母开头且最多15位");
nu:
scanf("%s", PsWd1);
if (PsWd1[0]<65 || PsWd1[0]>122 || (PsWd1[0] > 90 && PsWd1[0] < 97))
{
puts("必须以字母开头,请重新输入!");
fflush(stdin);
goto nu;
}
else if (strlen(PsWd1) < 5)
{
puts("密码过于简单,请重新输入!");
goto nu;
}
for (unsigned int i = 1; i<strlen(PsWd1); ++i)
{
if (PsWd1[i] >= 48 && PsWd1[i] <= 57)
{
p = 'F';
}
}
if (p != 'F')
{
puts("必须是字母与数字的组合,请重新输入!");
fflush(stdin);
goto nu;
}
puts("请再次输入你的密码!");
nu1:
scanf("%s", PsWd2);
if (strcmp(PsWd1, PsWd2))
{
puts("两次密码不符合!请重新输入!");
goto nu1;
}
return PsWd1;
}
Ps* LnitPsList()//注册用户
{
Ps*phead = NULL;
Ps*pnew = (Ps*)malloc(sizeof(Ps));
strcpy(pnew->Account, RegisterAccount(phead));
strcpy(pnew->PsWord, PsWord());
pnew->pnext = NULL;
phead = pnew;
TraversereMove2(phead);
return phead;
}
Ps* LnitPsListNew()
{
password = fopen("./账号密码.txt", "a+");
Ps* phead = NULL;
Ps* pthis = NULL;
rewind(password);
if (fgetc(password) == EOF)
{
puts("无账户信息!请注册");
fclose(password);
return LnitPsList();
}
rewind(password);
fseek(password, 0, 2);
int han = ftell(password) - 2;
fseek(password, 0, 0);
do
{
if (!phead)
{
pthis = (Ps*)malloc(sizeof(Ps));
fscanf(password, "%s%s", pthis->Account, pthis->PsWord);
pthis->pnext = NULL;
phead = pthis;
}
else
{
Ps * pnew = (Ps*)malloc(sizeof(Ps));
fscanf(password, "%s%s", pnew->Account, pnew->PsWord);
pnew->pnext = NULL;
pthis->pnext = pnew;
pthis = pthis->pnext;
}
} while (ftell(password) == han);
fclose(password);
return phead;
}
void AddList2(Ps const **phead)//再注册
{
puts("任意键继续输入,退出按ESC");
char g = _getch();
if (g == 27)
{
return;
}
Ps* pnew = (Ps*)malloc(sizeof(Ps));
strcpy(pnew->Account, RegisterAccount(*phead));
strcpy(pnew->PsWord, PsWord());
pnew->pnext = *phead;
*phead = pnew;
}
void Remove(Ps const **phead)//删除指定账号
{
puts("任意键继续输入,退出按ESC");
char g = _getch();
if (g == 27)
{
return;
}
char acc[16];
char p = 'T';
puts("输入需要删除信息的账号");
scanf("%s", acc);
Ps* pthis = *phead;
if (!strcmp((*phead)->Account, acc))
{
*phead = (*phead)->pnext;
free(pthis);
p = 'F';
}
else
{
while (pthis->pnext)
{
if (!strcmp(pthis->pnext->Account, acc))
{
Ps*ptemp = pthis->pnext;
pthis->pnext = ptemp->pnext;
free(ptemp);
p = 'F';
break;
}
pthis = pthis->pnext;
}
}
if (p == 'T')
{
puts("该账号不存在");
}
}
void ChangePsw(Ps const * phead)//修改密码
{
puts("任意键继续输入,退出按ESC");
char g = _getch();
if (g == 27)
{
return;
}
char Account[16];
char p = 'T';
nu:
puts("输入账号");
scanf("%s", Account);
while (phead)
{
if (!strcmp(phead->Account, Account))
{
puts("查找成功!");
strcpy(phead->PsWord, PsWord());
p = 'F';
break;
}
phead = phead->pnext;
}
if (p == 'T')
{
puts("账号不存在,重新输入");
goto nu;
}
}
void Release(Ps *phead)
{
while (phead)
{
Ps* pthis = phead;
phead = phead->pnext;
free(pthis);
}
}
int Register(Ps const * phead)//登录
{
char Account[16];
char PsWord[16];
puts("输入账号:");
scanf("%s", Account);
puts("输入密码");
scanf("%s", PsWord);
while (phead)
{
if (!strcmp(phead->Account, Account) && !strcmp(phead->PsWord, PsWord))
{
puts("登陆成功!");
return 1;
}
phead = phead->pnext;
}
puts("登录失败,账号或密码错误!");
return 0;
}
#include"password.h"
int DuplicateNu(stu * const phead)//学号查重
{
int num;
nu:
scanf("%d", &num);
char p = 'T';
stu* pthis = phead;
while (pthis)
{
if (pthis->num == num || num < 0)
{
p = 'F';
break;
}
pthis = pthis->pnext;
}
if (p == 'F')
{
puts("输入错误!学号有重复或小于零!请重新输入");
goto nu;
fflush(stdin);
}
else
{
return num;
}
}
char* DuplicateNa(stu * const phead)//姓名查重
{
static char name[32];
nu:
scanf("%s", name);
char p = 'T';
stu *pthis = phead;
while (pthis)
{
if (!strcmp(pthis->name, name))
{
p = 'F';
break;
}
pthis = pthis->pnext;
}
if (p == 'F')
{
puts("输入错误!名字有重复!请重新输入");
fflush(stdin);
goto nu;
}
else
{
return name;
}
}
char * JudgeeSex()//判断性别是否正常
{
static char sex[32];
nu0:
scanf("%s", sex);
if (strcmp(sex, "男") && strcmp(sex, "女"))
{
puts("输入错误,人只有两个性别,中国没有人妖!请重新输入性别!");
fflush(stdin);
goto nu0;
}
return sex;
}
int JudgeeAge()//判断年龄是否符合要求
{
int age;
nu1:
scanf("%d", &(age));
if (age < 0)
{
puts("输入错误!年龄不能小于零!请重新输入");
fflush(stdin);
goto nu1;
}
else if (age>120)
{
puts("输入错误!这货肯定不是人!请重新输入");
fflush(stdin);
goto nu1;
}
return age;
}
void TraversereMove(stu const* phead)//文件替换与保存
{
tempx = fopen("./临时文件.txt", "a+");
while (phead)
{
fprintf(tempx, "%d %d %s %s %s %s \n", phead->num, phead->age, phead->name, phead->sex, phead->class, phead->location);
phead = phead->pnext;
}
fclose(tempx);
if (!remove("学生管理系统.txt"))
{
puts("删除成功");
}
else
{
puts("删除失败");
}
if (!rename("临时文件.txt", "学生管理系统.txt"))
{
puts("更改成功");
}
else
{
puts("更改失败");
}
}
stu *List()//初始化链表
{
int num;
stu* pthis = NULL;
stu* pnext = NULL;
stu* phead = NULL;
printf("输入需要初始化的节点个数:\n");
num = getchar() - '0';
for (int i = 1; i <= num; ++i)
{
if (phead == NULL) //头节点不动
{
pthis = (stu*)malloc(sizeof(stu));
printf("输入学生%d的学号:\n", i);
nu:
scanf("%d", &(pthis->num));
if (pthis->num < 0)
{
puts("输入错误!学号不能小于零!请重新输入");
fflush(stdin);
goto nu;
}
printf("输入学生%d的姓名:\n", i);
fflush(stdin);
scanf("%s", pthis->name);
printf("输入学生%d的性别:\n", i);
strcpy(pthis->sex,JudgeeSex());
printf("输入学生%d的年龄:\n", i);
pthis->age = JudgeeAge();
printf("输入学生%d所在班级:\n", i);
scanf("%s", pthis->class);
printf("输入学生%d的家庭区域:\n", i);
scanf("%s", pthis->location);
pthis->pnext = NULL;
pthis->pfront = NULL;
phead = pthis;
}
else
{
stu* pnew=(stu*)malloc(sizeof(stu));
printf("输入学生%d的学号:\n", i);
pnew->num = DuplicateNu(phead);
printf("输入学生%d的姓名:\n", i);
strcpy(pnew->name, DuplicateNa(phead));
printf("输入学生%d的性别:\n", i);
strcpy(pnew->sex, JudgeeSex());
printf("输入学生%d的年龄:\n", i);
pnew->age = JudgeeAge();
printf("输入学生%d所在班级:\n", i);
scanf("%s", pnew->class);
printf("输入学生%d的家庭区域:\n", i);
scanf("%s", pnew->location);
pthis->pnext = pnew;
pthis->pnext->pnext = NULL;
pthis->pnext->pfront = pthis;
pthis = pthis->pnext;
}
}
TraversereMove(phead);//保存数据
return phead;
}
stu *ListNew()//从从数据库载入数据初始化链表
{
stud = fopen("./学生管理系统.txt", "a+");
stu* pthis = NULL;
stu* pnext = NULL;
stu* phead = NULL;
rewind(stud);
if (fgetc(stud) == EOF)
{
puts("数据库不存在,请初始化!");
fclose(stud);
return List();
}
puts("从数据库导入初始化成功!");
rewind(stud);
fseek(stud, 0, 2);
int han = ftell(stud) - 4;
fseek(stud, 0, 0);
do
{
if (phead == NULL) //头节点不动
{
pthis = (stu*)malloc(sizeof(stu));
fscanf(stud, "%d%d%s%s%s%s", &(pthis->num), &(pthis->age), pthis->name, pthis->sex, pthis->class, pthis->location);
pthis->pnext = NULL;
pthis->pfront = NULL;
phead = pthis;
}
else
{
pthis->pnext = (stu*)malloc(sizeof(stu));
fscanf(stud, "%d%d%s%s%s%s", &(pthis->pnext->num), &(pthis->pnext->age), pthis->pnext->name, pthis->pnext->sex, pthis->pnext->class, pthis->pnext->location);
pthis->pnext->pnext = NULL;
pthis->pnext->pfront = pthis;
pthis = pthis->pnext;
}
} while (ftell(stud) != han);
fclose(stud);
return phead;
}
void Traverse(stu const * phead)//遍历链表
{
while (phead)
{
printf("学生的学号为:%d\n 名字为:%s\n 性别为:%s\n 年龄为:%d\n 所在班级为:%s\n 所在家庭区域:%s\n", phead->num, phead->name, phead->sex, phead->age, phead->class, phead->location);
phead = phead->pnext;
}
}
void RangeSearch(stu * const phead)//范围搜索目标
{
char label = 'T';
char numtemp[32];
char agetemp[32];
char str[128];
no1:
puts("是否继续?退出按ESC,否则任意键继续");
char a = _getch();
if (a == 27)
{
return;
}
stu *pthis = phead;
puts("输入你要搜索的内容,提示:学号/姓名/性别/年龄/居住地等");
gets(str);
while (pthis)
{
_itoa(pthis->num, numtemp, 10);
_itoa(pthis->age, agetemp, 10);
if (!strcmp(str, numtemp) || !strcmp(str, agetemp) || !strcmp(str, pthis->name) || !strcmp(str, pthis->sex) || !strcmp(str, pthis->class) || !strcmp(str, pthis->location))
{
label = 'F';
printf("学生的学号为:%d\n 名字为:%s\n 性别为:%s\n 年龄为:%d\n 所在班级为:%s\n 所在家庭区域:%s\n", pthis->num, pthis->name, pthis->sex, pthis->age, pthis->class, pthis->location);
}
pthis = pthis->pnext;
}
if (label == 'T')
{
puts("查找失败,数据不存在,请重新输入!");
goto no1;
}
}
void AddList(stu** const phead)//增加节点
{
puts("任意键继续输入,退出按ESC");
char g = _getch();
if (g == 27)
{
return;
}
stu* pnew = (stu*)malloc(sizeof(stu));
pnew->pnext = NULL;
puts("录入学生学号");
pnew->num = DuplicateNu(*phead);
puts("录入学生姓名");
strcpy(pnew->name, DuplicateNa(*phead));
puts("录入学生性别");
strcpy(pnew->sex, JudgeeSex());
puts("录入学生年龄");
pnew->age = JudgeeAge();
puts("录入学生班级");
scanf("%s", pnew->class);
puts("录入学生家庭区域");
scanf("%s", pnew->location);
if ((*phead)->num > pnew->num)
{
pnew->pnext = *phead;
(*phead)->pfront = pnew;
pnew->pfront = NULL;
*phead = pnew;
}
else
{
stu* pthis = *phead;
while (pthis->pnext)
{
if (pthis->pnext->num > pnew->num)
{
pnew->pnext = pthis->pnext;
pthis->pnext->pfront = pnew;
pnew->pfront = pthis;
pthis->pnext = pnew;
break;
}
pthis = pthis->pnext;
}
pthis->pnext = pnew;
pnew->pfront = pthis;
}
}
void ChangeNode(stu ** const phead)//修改或删除学员信息
{
char b;
int n = -1;
char m;
char na[20];
do
{
NO0:
printf("输入要修改的学生学号或姓名,1.通过学号查找 2.通过姓名查找 退出按ESC键\n");
m = _getch();
switch (m)
{
case key_1:
printf("请输入学生学号:\n");
nu:
scanf("%d", &n);
if (n < 0)
{
puts("输入错误!学号不能小于零!请重新输入");
fflush(stdin);
goto nu;
}
break;
case key_2:
printf("请输入学生姓名:\n");
fflush(stdin);
scanf("%s", na);
break;
case key_ESC:
return;
break;
}
b = 'T';
stu* pthis = *phead;
stu* ptemp = NULL;
if ((*phead)->num == n || !strcmp((*phead)->name, na))
{
char l;
NO2:
printf("查找成功,选择需要的操作:1.删除输入 2.修改输入返回上一级按 ESC\n");
l = _getch();
switch (l)
{
case key_1:
*phead = pthis->pnext;
(*phead)->pfront = NULL;
free(pthis);
pthis = NULL;
break;
case key_2:
{
puts("输入1修改学号");
puts("输入2修改姓名");
puts("输入3修改性别");
puts("输入4修改年龄");
puts("输入5修改班级");
puts("输入6修改家庭区域");
puts("按ESC返回上一级");
char chonice = _getch();
switch (chonice)
{
case key_1:
puts("修改学生学号:");
pthis->num = DuplicateNu(*phead);
break;
case key_2:
puts("修改学生姓名:");
strcpy(pthis->name, DuplicateNa(*phead));
break;
case key_3:
puts("修改学生性别:");
strcpy(pthis->sex, JudgeeSex());
case key_4:
puts("修改学生年龄:");
pthis->age = JudgeeAge();
break;
case key_5:
puts("修改学生班级:");
scanf("%s", pthis->class);
break;
case key_6:
puts("修改学生家庭区域:");
scanf("%s", pthis->location);
break;
case key_ESC:
goto NO2;
}
break;
}
case key_ESC:
goto NO0;
break;
}
b = 'F';
}
else
{
while (pthis->pnext)
{
if (pthis->pnext->num == n || !strcmp(pthis->pnext->name, na))
{
int l;
printf("查找成功,选择需要的操作:1.删除输入 2.修改输入 返回按 ESC\n");
l = _getch();
switch (l)
{
case key_1:
ptemp = pthis->pnext;
pthis->pnext = ptemp->pnext;
if (ptemp->pnext != NULL)
ptemp->pnext->pfront = pthis;
free(ptemp);
ptemp = NULL;
break;
case key_2:
puts("1.修改学号");
puts("2.修改姓名");
puts("3.修改性别");
puts("4.修改年龄");
puts("5.修改班级");
puts("6.修改家庭区域");
char chonice = _getch();
switch (chonice)
{
case key_1:
puts("修改学生学号:");
pthis->pnext->num = DuplicateNu(*phead);
break;
case key_2:
puts("修改学生姓名:");
strcpy(pthis->pnext->name, DuplicateNa(*phead));
break;
case key_3:
puts("修改学生性别:");
strcpy(pthis->pnext->sex, JudgeeSex());
break;
case key_4:
puts("修改学生年龄:");
pthis->pnext->age = JudgeeAge();
break;
case key_5:
puts("修改学生班级:");
scanf("%s", pthis->pnext->class);
break;
case key_6:
puts("修改学生家庭区域:");
scanf("%s", pthis->pnext->location);
break;
}
break;
case key_ESC:
return;
break;
}
b = 'F';
break;
}
pthis = pthis->pnext;
}
}
if (b == 'T')
{
printf("输入信息有误,请重输入\n");
}
fflush(stdin);
} while (b == 'T');
}
void Release2(stu *phead)//释放链表
{
stu* pthis;
while (phead)
{
pthis = phead;
phead = phead->pnext;
free(pthis);
pthis = NULL;
}
}
void SwapInteger(int* const num1, int* const num2)//交换整形
{
*num1 ^= *num2;
*num2 ^= *num1;
*num1 ^= *num2;
}
void SwapString(char * const str1, char * const str2)//交换字符串
{
char temp[32];
strcpy(temp, str1);
strcpy(str1, str2);
strcpy(str2, temp);
}
void Sorting(stu * const phead)//链表排序(冒泡排序)
{
stu *pthis = phead;
stu *ptemp = phead;
while (pthis)
{
ptemp = pthis;
while (ptemp->pnext)
{
if (pthis->num >= ptemp->pnext->num)
{
SwapInteger(&(pthis->num), &(ptemp->pnext->num));
SwapInteger(&(pthis->age), &(ptemp->pnext->age));
SwapString(pthis->name, ptemp->pnext->name);
SwapString(pthis->sex, ptemp->pnext->sex);
SwapString(pthis->class, ptemp->pnext->class);
SwapString(pthis->location, ptemp->pnext->location);
}
ptemp = ptemp->pnext;
if (ptemp == NULL)
{
break;
}
}
pthis = pthis->pnext;
}
}
int main()
{
Ps* phead1 = LnitPsListNew();
/*system("cls");*/
while (1)
{
char k;
nu3:
puts("████████████████████████████████████████████");
puts("██████████████████ 学生管理系统 ███████████████████");
puts("███████████████████1登录账户 ████████████████████");
puts("███████████████████2注册账户 ████████████████████");
puts("███████████████████3删除账户 ████████████████████");
puts("███████████████████4修改密码 ████████████████████");
puts("███████████████████按ESC退出 ████████████████████");
puts("████████████████████████████████████████████");
k = _getch();
switch (k)
{
case key_1:
nu1:
if (Register(phead1))
{
goto nu0;
}
else
{
puts("1.重新输入2.没有账户,去注册 按ESC返回");
char n = _getch();
switch (n)
{
case key_1:
goto nu1;
break;
case key_2:
goto nu2;
break;
case key_ESC:
goto nu3;
break;
}
}
break;
case key_2:
nu2:
AddList2(&phead1);//再注册
TraversereMove2(phead1);
break;
case key_3:
Remove(&phead1);//删除指定账号
TraversereMove2(phead1);
break;
case key_4:
ChangePsw(phead1);//修改密码
TraversereMove2(phead1);
break;
case key_ESC:
goto no1;
break;
}
}
nu0:{}
stu* phead = ListNew();
/*system("cls");*/
while (1)
{
char k;
puts("██████████████████████████████████████████████");
puts("███████████████████ 学生管理系统 ████████████████████");
puts("███████████████████1学生档案查询 ████████████████████");
puts("███████████████████2添加学生信息 ████████████████████");
puts("███████████████████3查找修改信息 ████████████████████");
puts("███████████████████4一键查询内容 ████████████████████");
puts("███████████████████ 按退出键退出 ████████████████████");
puts("██████████████████████████████████████████████");
k = _getch();
switch (k)
{
case key_1:
Traverse(phead);//遍历数据
break;
case key_2:
AddList(&phead);//添加信息
TraversereMove(phead);//保存数据
Traverse(phead);//遍历数据
break;
case key_3:
ChangeNode(&phead);//查找更改信息
Sorting(phead);//自动按学号排序
TraversereMove(phead);//保存数据
Traverse(phead);
break;
case key_4:
RangeSearch(phead);//范围搜索,只支持完整名词搜索,不支持模糊查询,输入学号或名字或性别或年龄或班级或居住地
break;
case key_ESC:
puts("是否继续退出?按ESC返回,否则任意键继续");
char m = _getch();
if (m != 27)
{
goto no0;
}
break;
}
}
no0:
Release2(phead);//清空整个链表
no1:
Release(phead1);//清空整个链表
system("pause");
return 0;
}