//1、所有头文件
#include<string.h>
#include <unistd.h>
//学生结构体的定义
struct student
{
int id; //学号
char name[20]; //姓名
char sex[10]; //性别
int age; //年龄
char password[20]; //密码
int class_number; //所在班级
float cscore; //语文成绩
float mscore; //数学成绩
float escore; //英语成绩
float total; //总分,不需用输入,计算而得
int rank; //排名
};
extern struct link* amao;
struct link* amao_node;
struct link
{
struct student data;
struct link* next;
};
#endif
//控制层头文件
#ifndef CONTROL_H
#define CONTROL_H
void admin();
void add(); //1.管理员添加学生信息
void amend(); //修改学生记录.先按输入的学号查询到该记录,然后提示用户修改学号之外的值,学号不能修改
void del(); //删除学生信息
void query_name(); //根据姓名查询学生信息
void query_escore(); //根据英语成绩查询学生信息
void query_rank(); //根据名次查询学生信息
#endif
//
#ifndef GETCH_H
#define GETCH_H
#include <sys/stat.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <time.h>
#include <termios.h>
int getch();
void getPassword(char *pcPWD);
#endif//
#ifndef LINK_H
#define LINK_H
void inserAfter(struct link* head,struct student data); //1.函数功能:后向插入新结点
struct link* createNode(struct student data); //2.函数功能:在堆空间上创建一个新结点
struct link* selectByName(struct link* head,char* name); //3.函数功能:根据name 查询 结点并返回该结点上一个结点
struct link* selectByEscore(struct link* head,float* p); //3.1函数功能:根据escore 查询 结点并返回该结点上一个结点
struct link* selectByRank(struct link* head,float* p); //3.2函数功能:根据rank 查询 结点并返回该结点上一个结点
void delByName(struct link* head,char* name); //4.函数功能:根据name 删除结点
void printfAll(struct link* head); //5,函数功能:遍历链表打印所有的结点
void freeAll(struct link* head); //6,函数功能:释放所有的结点
void sortLink(struct link* head); //7.函数功能:排序所有结点
void selectSort(struct link* head); //7.1函数功能:排序后输出名次
void save(struct link* head); //8.函数功能:保存所有的结点
void load(struct link* head); //9.函数功能:加载所有的结点
void adminPassword(); //10.管理员账户和密码验证
void userPassword(); //10.1学生的账户和密码验证
void amendByName(struct link* head,char* name); //11.函数功能:根据name 修改结点
void userAmendByName(struct link* head,char* name); //12.学生修改密码
void printfAll1(struct link* head);
void sortLinkByName(struct link* head); //13.1根据姓名排序
void printfAllByName(struct link* head); //13.2根据姓名排序打印
void sortLinkByEscore(struct link* head); //14.1根据英语成绩排序
void printfAllByEscore(struct link* head); //14.2根据英语成绩排序打印
void sortLinkByRank(struct link* head); //15.1根据名次排序
void printfAllByRank(struct link* head); //15.2根据名次排序打印
#endif//学生登录项密码头文件
#ifndef USRE_H
#define USER_H
void queryUser();
void user_password_amend();
#endif
//所有菜单头文件
#ifndef VIEW_H
#define VIEW_H
void menu(); //1.登录主界面
void menu_admin(); //2.管理员登录二级菜单
void menu_student(); //3.学生登录二级菜单
void menu_query(); //4.查询菜单
#endif
以上是包含的所有头文件,有些乱哈!!!
//开始写源程序
//
界面层程序
#include"std.h"
#include"view.h"
#include"link.h"
#include"control.h"
#include"user.h"
struct link* amao;
//1.登录界面
void menu()
{
int i = 0;
system("clear");
printf(" \033[34m╭\033[30m──\033[31m──\033[32m──\033[33m──\033[34m──\033[35m──\033[36m──\033[37m──\033[32m──\033[31m──\033[32m──\033[37m──\033[36m──\033[35m──\033[34m──\033[33m──\033[32m──\033[31m──\033[32m──\033[33m──\033[34m──\033[35m╮\033[0m\n");
printf(" \033[30m│\033[0m \033[41m**欢迎使用学生管理系统**\033[0m \033[30m│\033[0m\n");
printf(" \033[31m│\033[0m \033[31m│\033[0m\n");
printf(" \033[32m│\033[0m \033[32m│\033[0m\n");
printf(" \033[33m│\033[0m\033[32m 【1】\033[0m\033[34m管理员登录 \033[0m \033[33m│\033[0m\n");
printf(" \033[34m│\033[0m\033[32m 【2】\033[0m\033[34m学生登录 \033[0m \033[34m│\033[0m\n");
printf(" \033[35m│\033[0m\033[32m 【0】\033[0m\033[34m退出系统 \033[0m \033[35m│\033[0m\n");
printf(" \033[36m│\033[0m \033[36m │\033[0m\n");
printf(" \033[34m╰\033[30m──\033[31m──\033[32m──\033[33m──\033[34m──\033[35m──\033[36m──\033[37m──\033[32m──\033[31m──\033[32m──\033[37m──\033[36m──\033[35m──\033[34m──\033[33m──\033[32m──\033[31m──\033[32m──\033[33m──\033[34m──\033[35m╯\033[0m\n");
printf("\033[32m请您选择相应功能进行操作!\033[0m \n");
while(1)
{
scanf("%d",&i);
switch(i)
{
case 1:
adminPassword();
sleep(2);
admin();
break;
case 2:
userPassword();
sleep(2);
menu_student();
break;
case 0:
save(amao);
freeAll(amao);
amao = NULL;
break ;
default:
printf( "\033[32m数字输入有误,请重新输入!\033[0m\n");
break;
}
if(i==0)
{
exit(0);
}
}
}
//2.管理员登录二级界面
void menu_admin()
{
system("clear");
printf("\033[34m╭\033[31m──\033[32m──\033[33m──\033[34m──\033[35m──\033[36m──\033[37m──\033[31m──\033[32m──\033[33m──\033[34m──\033[35m──\033[36m──\033[37m──\033[31m──\033[34m─╮\033[0m\n");
printf("\033[31m│\033[0m \033[41m**欢迎进入管理员界面**\033[0m \033[31m│\033[0m\n");
printf("\033[32m│\033[0m \033[32m│\033[0m\n");
printf("\033[33m│\033[0m \033[32m【1】\033[0m\033[34m查看所有学员\033[0m \033[33m│\033[0m\n");
printf("\033[34m│\033[0m \033[32m【2】\033[0m\033[34m增加学员\033[0m \033[34m│\033[0m\n");
printf("\033[35m│\033[0m \033[32m【3】\033[0m\033[34m修改学员\033[0m \033[35m│\033[0m\n");
printf("\033[36m│\033[0m \033[32m【4】\033[0m\033[34m查询\033[0m \033[36m│\033[0m\n");
printf("\033[37m│ \033[0m \033[32m【5】\033[0m\033[34m排序\033[0m \033[37m│\033[0m\n");
printf("\033[31m│\033[0m \033[32m【6】\033[0m\033[34m删除\033[0m \033[31m│\033[0m\n");
printf("\033[32m│\033[0m \033[32m【0】\033[0m\033[34m返回上一级\033[0m \033[32m│\033[0m\n");
printf("\033[34m╰\033[31m──\033[32m──\033[33m──\033[34m──\033[35m──\033[36m──\033[37m──\033[31m──\033[32m──\033[33m──\033[34m──\033[35m──\033[36m──\033[37m──\033[31m──\033[34m─╯\033[0m\n");
printf("\033[32m请您选择相应功能进行操作!\033[0m\n");
}
//查询学生信息(1、根据姓名 2、根据单科成绩(英语) 、3根据排名)
void menu_query()
{
while(1)
{
int i = 0;
char ch;
system("clear");
printf("\n");
printf("\033[32m╭─\033[31m──\033[32m──\033[33m──\033[34m──\033[35m──\033[36m──\033[37m──\033[36m──\033[35m──\033[34m──\033[33m──\033[32m──\033[31m──\033[32m──\033[33m──\033[34m╮\033[0m\n");
printf("\033[31m│\033[0m \033[41m**欢迎进入查询界面**\033[0m \033[31m│\033[0m\n");
printf("\033[32m│\033[0m \033[32m│\033[0m\n");
printf("\033[33m│\033[0m \033[32m【1】\033[0m\033[34m根据姓名查询\033[0m \033[33m│\033[0m\n");
printf("\033[34m│\033[0m \033[32m【2】\033[0m\033[34m根据成绩查询(英语)\033[0m \033[34m│\033[0m\n");
printf("\033[35m│\033[0m \033[32m【3】\033[0m\033[34m根据名次查询\033[0m \033[35m│\033[0m\n");
printf("\033[36m│\033[0m \033[32m【0】\033[0m\033[34m返回上一级\033[0m \033[36m│\033[0m\n");
printf("\033[32m╰─\033[31m──\033[32m──\033[33m──\033[34m──\033[35m──\033[36m──\033[37m──\033[32m──\033[35m──\033[34m──\033[33m──\033[32m──\033[31m──\033[32m──\033[33m──\033[34m╯\033[0m\n");
printf("\033[32m请您选择相应功能进行操作!\033[0m\n");
scanf("%d",&i);
while(getchar()!='\n');
switch(i)
{
case 1:
query_name(); //根据姓名查询
break;
case 2:
query_escore(); //根据英语成绩查询
break;
case 3:
query_rank(); //根据名次查询
break;
case 0: //返回上一级
return ;
default:
printf("\033[32m数字输入有误,请重新输入!\033[0m\n");
break;
}
printf("\033[32m是否继续查询学生信息或退出查询功能?(y/n)\033[0m\n");
while(getchar()!='\n');
scanf("%c",&ch);
if(ch=='y'||ch=='Y')
{
continue;
}else{
return ;
}
}
}
//学生信息排序(1、根据姓名 2、根据单科成绩(英语) 、3根据排名)
void menu_sort()
{
while(1)
{
int i = 0;
system("clear");
printf("\n");
printf("\033[32m╭─\033[31m──\033[32m──\033[33m──\033[34m──\033[35m──\033[36m──\033[37m──\033[32m──\033[36m──\033[35m──\033[34m──\033[33m──\033[32m──\033[31m──\033[32m──\033[33m╮\033[0m\n");
printf("\033[31m│\033[0m \033[41m**欢迎进入排序界面**\033[0m \033[31m│\033[0m\n");
printf("\033[32m│\033[0m \033[32m│\033[0m\n");
printf("\033[33m│\033[0m \033[32m【1】\033[0m\033[34m根据姓名排序\033[0m \033[32m│\033[0m\n");
printf("\033[34m│\033[0m \033[32m【2】\033[0m\033[34m根据英语成绩排序\033[0m \033[33m│\033[0m\n");
printf("\033[35m│\033[0m \033[32m【3】\033[0m\033[34m根据名次排序\033[0m \033[34m│\033[0m\n");
printf("\033[36m│\033[0m \033[32m【0】\033[0m\033[34m返回上一级\033[0m \033[35m│\033[0m\n");
printf("\033[37m╰─\033[32m──\033[33m──\033[34m──\033[35m──\033[36m──\033[32m──\033[31m──\033[32m──\033[33m──\033[34m──\033[35m──\033[36m──\033[37m──\033[31m──\033[32m──\033[33m╯\033[0m\n");
printf("\033[32m请您选择相应功能进行操作!\033[0m\n");
scanf("%d",&i);
while(getchar()!='\n');
switch(i)
{
case 1:
sortLinkByName(amao); //根据姓名排序
printfAllByName(amao);
break;
case 2:
sortLinkByEscore(amao); //根据单科成绩排序
printfAllByEscore(amao);
break;
case 3:
sortLinkByRank(amao);
printfAllByRank(amao);
//sortLink(amao);
//printfAll1(amao); //根据名次排序
break;
case 0: //返回上一级
admin();
break;
default:
printf("\033[32m数字输入有误,请重新输入!\033[0m\n");
break;
}
}
}
//3.学生登录二级界面
void menu_student()
{
while(1)
{
int i = 0;
system("clear");
printf("\033[32m╭─\033[31m──\033[32m──\033[33m──\033[34m──\033[35m──\033[36m──\033[37m──\033[36m──\033[35m──\033[34m──\033[33m──\033[32m──\033[31m──\033[32m──\033[33m──\033[34m╮\033[0m\n");
printf("\033[31m│\033[0m \033[41m**欢迎进入学生界面**\033[0m \033[31m│\033[0m\n");
printf("\033[32m│\033[0m \033[32m│\033[0m\n");
printf("\033[33m│\033[0m \033[32m【1】\033[0m\033[34m查看个人信息\033[0m \033[33m│\033[0m\n");
printf("\033[34m│\033[0m \033[32m【2】\033[0m\033[34m修改密码\033[0m \033[34m│\033[0m\n");
printf("\033[35m│\033[0m \033[32m【0】\033[0m\033[34m返回上一级\033[0m \033[35m│\033[0m\n");
printf("\033[36m│\033[0m \033[36m│\033[0m\n");
printf("\033[32m╰─\033[31m──\033[32m──\033[33m──\033[34m──\033[35m──\033[36m──\033[37m──\033[36m──\033[35m──\033[34m──\033[33m──\033[32m──\033[31m──\033[32m──\033[33m──\033[32m╯\033[0m\n");
printf("\033[32m请您选择相应功能进行操作!\033[0m\n");
scanf("%d",&i);
switch(i)
{
case 1:
queryUser() ;//查看个人信息
break;
case 2:
user_password_amend();//修改密码
break;
case 0: //返回上一级
menu ();
break;
default:
printf("\033[32m数字输入有误,请重新输入!\033[0m\n");
break;
}
}
}
//
#include"std.h"
#include"control.h"
#include"view.h"
#include"link.h"
#include"user.h"
//1.管理员功能的实现
void admin()
{
int i = 0;
system("clear");
while(1)
{
menu_admin();
scanf("%d",&i);
while(getchar()!='\n');
switch(i)
{
case 1:
sortLink(amao);
printfAll(amao); //查看所有学员
break;
case 2:
add(); //增加学员
save(amao);
break;
case 3:
amend(); //修改学员
break;
case 4:
menu_query(); //查询学员
break;
case 5:
menu_sort(); //排序
break;
case 6:
del(); //删除
break;
case 0: //返回上一级
menu();
break;
default:
system("clear");
printf("\n\n");
printf("**********数字输入有误,请重新输入!**********\n");
printf("\n\n");
sleep(2);
break;
}
}
}
//2.管理员添加学生信息
void add()
{
while(1)
{
char ch;
system("clear");
struct student data;
printf("*************************\n");
printf("请输入学生的信息...\n");
printf("*************************\n");
printf("请输入学生的学号:");
scanf("%d",&data.id);
printf("请输入学生的姓名:");
scanf("%s",data.name);
printf("请输入学生的性别:");
scanf("%s",data.sex);
printf("请输入学生的年龄:");
scanf("%d",&data.age);
printf("请输入学生的密码:");
scanf("%s",data.password);
printf("请输入学生的所在班级:");
scanf("%d",&data.class_number);
printf("请输入学生的语文成绩:");
scanf("%f",&data.cscore);
printf("请输入学生的数学成绩:");
scanf("%f",&data.mscore);
printf("请输入学生的英语成绩:");
scanf("%f",&data.escore);
data.total = data.cscore + data.mscore + data.escore;
struct link* pre = selectByName(amao,data.name);
if(pre != NULL)
{
system("clear");
printf("\n\n");
printf("**********%s已经存在,请重新增加!**********\n",data.name);
printf("\n\n");
sleep(3);
return ;
}
inserAfter(amao,data);
//*******************************************************名次的排序
selectSort(amao);
int i = 1;
struct link * newHead= amao;
newHead = newHead->next;
while(newHead!=NULL)
{
newHead->data.rank = i;
i++;
newHead = newHead->next;
}
save(amao);
//********************************************************
printf("学生信息添加成功!\n");
printf("******************************\n");
printf("是否继续添加学生信息或退出添加功能?(y/n)\n");
while(getchar()!='\n');
scanf("%c",&ch);
if(ch=='y'||ch=='Y')
{
continue;
}else{
return ;
}
}
}
//删除学生
void del()
{
while(1)
{
char ch;
char name[20] = "";
printf("请输入你想删除的学生姓名\n");
scanf("%s",name);
struct link* pre = selectByName(amao,name);
if(pre == NULL)
{
system("clear");
printf("\n\n");
printf("**********该姓名不存在!**********\n");
printf("\n\n");
sleep(3);
return ;
}
delByName(amao,name);
printf("删除成功!\n");
printf("请选择是否继续删除学生信息或退出?(y/n)\n");
while(getchar()!='\n');
scanf("%c",&ch);
if(ch=='y'||ch=='Y')
{
continue;
}else{
return ;
}
}
}
//根据姓名查看学生信息
void query_name()
{
char name[20] = "";
printf("请输入你想查询的学生姓名:");
scanf("%s",name);
struct link* pre = selectByName(amao,name);
if(pre == NULL)
{
printf("该姓名不存在!\n");
return ;
}
pre = pre -> next;
printf("姓名\t\t学号\t性别\t年龄\t 密码\t\t 班级\t 语文\t 数学\t 英语\t 总分\t 名次\n");
printf("%s\t %d\t %s\t %d\t %s\t\t %d\t %.2f\t %.2f\t %.2f\t %.2f\t %d\n",pre->data.name,pre->data.id,pre->data.sex,pre->data.age,pre->data.password,pre->data.class_number,pre->data.cscore,pre->data.mscore,pre->data.escore,pre->data.total,pre->data.rank);
}
//根据英语成绩查看学生信息
void query_escore()
{
float es = 0;
printf("请输入你想查询的学生的英语成绩:");
scanf("%f",&es);
float *p = &es;
struct link* pre = selectByEscore(amao,p);
if(pre == NULL)
{
printf("该姓名不存在!\n");
return ;
}
pre = pre -> next;
printf("英语\t 姓名\t\t学号\t性别\t年龄\t 密码\t\t 班级\t 语文\t 数学\t 总分\t 名次\n");
printf("%.2f\t %s\t %d\t %s\t %d\t %s\t\t %d\t %.2f\t %.2f\t %.2f\t %d\n",pre->data.escore,pre->data.name,pre->data.id,pre->data.sex,pre->data.age,pre->data.password,pre->data.class_number,pre->data.cscore,pre->data.mscore,pre->data.total,pre->data.rank);
}
//根据rank查看学生信息
void query_rank()
{
float es = 0;
printf("请输入你想查询的学生的名次:");
scanf("%f",&es);
float *p = &es;
struct link* pre = selectByRank(amao,p);
if(pre == NULL)
{
printf("该姓名不存在!\n");
return ;
}
pre = pre -> next;
printf("英语\t 姓名\t\t学号\t性别\t年龄\t 密码\t\t 班级\t 语文\t 数学\t 总分\t 名次\n");
printf("%.2f\t %s\t\t %d\t %s\t %d\t %s\t\t %d\t %.2f\t %.2f\t %.2f\t %d\n",pre->data.escore,pre->data.name,pre->data.id,pre->data.sex,pre->data.age,pre->data.password,pre->data.class_number,pre->data.cscore,pre->data.mscore,pre->data.total,pre->data.rank);
}
//修改学生
void amend()
{
while(1)
{
char ch;
char name[20] = "";
printf("请输入你想修改的学生姓名\n");
scanf("%s",name);
struct link* pre = selectByName(amao,name);
if(pre == NULL)
{
system("clear");
printf("\n\n");
printf("**********该姓名不存在!**********\n");
printf("\n\n");
sleep(3);
return ;
}
amendByName(amao,name);
printf("修改成功!\n");
printf("请选择是否继续修改学生信息或退出?(y/n)\n");
while(getchar()!='\n');
scanf("%c",&ch);
if(ch=='y'||ch=='Y')
{
continue;
}else{
return ;
}
}
}
//链表
#include"getch.h"
/*****************************************
* 功能:设置终端为不回显不缓冲,并获取按键的键值
* 返回值:按键的键值int型
* 参数:无参数
****************************************/
int getch()
{
struct termios tm, tm_old;
int fd = STDIN_FILENO, c;
if(tcgetattr(fd, &tm) < 0) //
{
return -1;
}
tm_old = tm;
cfmakeraw(&tm); //就是将终端设置为原始模式,该模式下所有的输入数据以字节为单位被处理。
//在原始模式下,终端是不可回显的,而且所有特定的终端输入/输出模式不可用。
if(tcsetattr(fd, TCSANOW, &tm) < 0) //不等数据传输完毕就立即改变属性 成功返回0 失败-1
{
return -1;
}
c = fgetc(stdin);//
if(tcsetattr(fd, TCSANOW, &tm_old) < 0)
{
return -1;
}
return c;
}
/*****************************************
* 功能:调用getch获取键值保存到pcPWD中并单个回显*
* 可以分别backspace和回车
* 用于获取密码
* 返回值:无返回值
* 参数:字符数组指针pcPWD
****************************************/
void getPassword(char *pcPWD)
{
int ch=0;
int i=0;
for(i=0;i<20;)
{
ch=getch();
if(ch==-1)
{
continue;
}
if((ch == 127 || ch == 8) && i>0)
{
putchar('\b');
putchar(' ');
putchar('\b');
i--;
}
else if(ch==10 || ch == 13)
{
pcPWD[i]=0;
putchar('\n');
return;
}
else if(i==0&&(ch==127 ||ch == 8))
{
printf("\a");
}
else if(i<19)
{
pcPWD[i]=(char)ch;
putchar('*');
i++;
}
else
{
printf("\a");
}
}
}//
#include"std.h"
#include"link.h"
#include"control.h"
#include"view.h"
#include"user.h"
#include"getch.h"
//1.函数功能:在堆空间上创建一个新结点
//参数列表 :data,给新的堆空间里面的值域赋值
//函数返回值:返回堆空间首地址
struct link* createNode(struct student data)
{
struct link* newNode = calloc(1,sizeof(struct link));
newNode -> data = data;
newNode -> next = NULL;
return newNode;
}
//2.函数功能:后向插入新结点
//参数列表 :head:头结点(第一个结点),data:要给新结点赋值的值域(在外面键入的)
//函数返回值:void 不需要返回值
void inserAfter(struct link* head,struct student data)
{
if(NULL == head)
{
printf(" head is null\n");
return ;
}
while( head -> next != NULL)
{
head = head -> next;
}
struct link* newNode = createNode(data); //创建一个节点
head -> next = newNode; //最后一个节点指向一个新的节点
}
//3.函数功能:根据name 查询结点,并返回该结点上一个结点
//参数列表 :head:头结点,name :你要查找的姓名,可以替 换成int age….
//函数返回值:返回找到结点的前一个结点,NULL表示没找到或者出错
struct link* selectByName(struct link* head,char* name)
{
if( head == NULL)
{
printf(" head is NULL\n");
return NULL;
}
struct link* pre = head;
head = head -> next;
while( head != NULL)
{
if( strcmp(head -> data.name,name)==0)
{
return pre;
}
pre = head;
head = head -> next;
}
return NULL;
}
//3.1函数功能:根据escore 查询结点,并返回该结点上一个结点
//参数列表 :head:头结点,escore :你要查找的成绩,可以替 换成int age….
//函数返回值:返回找到结点的前一个结点,NULL表示没找到或者出错
struct link* selectByEscore(struct link* head,float* p)
{
if( head == NULL)
{
printf(" head is NULL\n");
return NULL;
}
struct link* pre = head;
head = head -> next;
while( head != NULL)
{
if(head -> data.escore == *p)
{
return pre;
}
pre = head;
head = head -> next;
}
return NULL;
}
//3.2函数功能:根据rank 查询结点,并返回该结点上一个结点
//参数列表 :head:头结点,rank :你要查找的成绩,可以替 换成int age….
//函数返回值:返回找到结点的前一个结点,NULL表示没找到或者出错
struct link* selectByRank(struct link* head,float* p)
{
if( head == NULL)
{
printf(" head is NULL\n");
return NULL;
}
struct link* pre = head;
head = head -> next;
while( head != NULL)
{
if(head -> data.rank == *p)
{
return pre;
}
pre = head;
head = head -> next;
}
return NULL;
}
//4.函数功能:根据name 删除结点
//参数列表 :head头结点,name :你要删除的结点的姓名
//函数返回值:void 不需要返回值
void delByName(struct link* head,char* name)
{
if( head == NULL)
{
printf(" head is NULL\n");
return ;
}
//find the pre
struct link* pre = selectByName(head,name);
if(pre == NULL)
{
printf("can not find the node\n");
return ;
}
//delete the node
struct link* del = pre -> next;
pre -> next = del -> next;
//free the node
free(del);
del = NULL;
}
//5,函数功能:遍历链表打印所有的结点
//参数列表 :head头结点
//函数返回值:void 不需要返回值
void printfAll(struct link* head)
{
char a;
system("clear");
if( head == NULL)
{
printf(" head is NULL\n");
return ;
}
head = head -> next;
printf("学号\t 姓名\t\t性别\t年龄\t 密码\t\t班级\t 语文\t 数学\t 英语\t 总分\t 名次\n");
while( head != NULL)
{
printf("%d\t %s\t\t %s\t %d\t %s\t\t %d\t %.2f\t %.2f\t %.2f\t %.2f\t %d\n",head->data.id,head->data.name,head->data.sex,head->data.age,head->data.password,head->data.class_number,head->data.cscore,head->data.mscore,head->data.escore,head->data.total,head->data.rank);
head = head -> next;
}
printf("以上是全部学员信息!\n");
printf("******************************\n");
printf("按任意键继续~~~\n");
scanf("%c",&a);
return ;
}
//6,函数功能:释放所有的结点
//参数列表 :head头结点
//函数返回值:void 不需要返回值
void freeAll(struct link* head)
{
if( NULL == head)
{
printf(" head is null\n");
return ;
}
while(head != NULL)
{
struct link* save = head->next;
free(head);
head = save;
}
}
//7.函数功能:排序所有结点
//参数列表 :head头结点
//函数返回值:void 不需要返回值
void sortLink(struct link* head)
{
if( NULL == head)
{
printf(" head is null\n");
return ;
}
struct link* save = head -> next;
head = head -> next;
int length = 0;
while(head != NULL)
{
head = head -> next;
length++;
}
int i = 0,j = 0;
for(i = 0;i<length-1;i++)
{
//传入头节点
head = save;
for(j = 0;j<length -i - 1;j++)
{
struct link* agou1 = head;
struct link* agou2 = head->next;
if((agou1->data.total) < (agou2->data.total))
{
struct student data = agou1->data;
agou1->data = agou2->data;
agou2->data = data;
}
head = head -> next;
}
}
}
//7.1函数功能:排序后输出名次
//参数列表 :head头结点
//函数返回值:void 不需要返回值
void selectSort(struct link* head)
{
struct link *min = NULL;//中间变量,存放最小值
struct link *p = NULL;//链表中参加比较的数
struct link *min_p = NULL;//存放最小值前面的指针
struct link *newhead = NULL;//存放最小值前面的指针
struct link *newtail = NULL;//先链表的尾指针
struct link* old = head;
head = head->next;
//对原链表进行循环,找出最小值
while(head != NULL)
{
//循环一次,找到一个最小值
for(min = head,p=head;p->next != NULL;p=p->next)
{
if(p->next->data.total > min->data.total) //********************************************此处 需要改
{
min=p->next;
min_p = p;
}
}
//找到最小值后,将最小值放入新的链表中,采用后向插入法
if(NULL == newhead)
{
newhead = min;
}
else
{
newtail->next = min;
}
newtail = min;
//找到最小值后,将原链表中的这个值删除
if(min == head)
{
head = head->next;
}
else
{
min_p->next = min->next;
}
}
//排序完成后,为新的链表的最后一个节点做结束标志
old->next = newhead;
}
//8.函数功能:保存所有的结点
//参数列表 :head头结点
//函数返回值:void 不需要返回值
void save(struct link* head)
{
if( head == NULL)
{
printf(" head is null\n");
return ;
}
FILE* fp = fopen("amao.txt","w+");
head = head -> next;
while( head != NULL)
{
fwrite(&head->data,sizeof(struct student),1,fp);
head = head -> next;
}
fclose(fp);
}
//9.函数功能:加载所有的结点
//参数列表 :head头结点
//函数返回值:void 不需要返回值
void load(struct link* head)
{
if( NULL == head)
{
printf("head is null\n");
return ;
}
FILE *fp = fopen("amao.txt","r+");
if(NULL == fp)
{
return ;
}
while(1)
{
struct student data;
int res = fread(&data,sizeof(struct student),1,fp);
if( res < 1)
{
break;
}
inserAfter(head,data);
}
fclose(fp);
}
//10.函数功能:管理员账户和密码验证
//参数列表 :无
//函数返回值:void 不需要返回值
void adminPassword()
{
int i = 0;
char name[] = "admin",pass[] = "123456";
char pname[20] = {0},ppass[20] ={0};
printf("请输入管理员账户...\n");
scanf("%s",pname);
for(i=0;i<3;i++)
{
printf("请输入密码...\n");
while(getchar()!='\n');
getPassword(ppass);
if( strcmp(name,pname)!=0||strcmp(pass,ppass)!=0)
{
printf("您输入的账户名和密码有误,请重新输入...\n");
continue ;
}else{
a:srand((unsigned)time(0));
char yzm[5] = "\0";
char yzm1[5] = "\0";
int length = sizeof(yzm)/sizeof(char);
for(i=0;i<length-1;i++)
{
yzm[i] = random()&+'a';
}
printf("验证码:%s\n",yzm);
printf("请输入验证码:");
scanf("%s",yzm1);
if(strcmp(yzm,yzm1) !=0)
{
printf("验证码输入错误!\n");
goto a;
}else{
system("clear");
printf("\n\n");
printf("\033[41;37m**********登录成功,欢迎使用!**********\033[0m\n");
printf("\n\n");
return ;
}
}
}
menu();
}
//11.函数功能:根据name 修改结点
//参数列表 :head头结点,name :你要修改的结点的姓名
//函数返回值:void 不需要返回值
void amendByName(struct link* head,char* name)
{
if( head == NULL)
{
printf(" head is NULL\n");
return ;
}
//find the pre
struct link* pre = selectByName(head,name);
if(pre == NULL)
{
printf("can not find the node\n");
return ;
}
struct link* save = pre -> next;
printf("*************************\n");
printf("请输入学生的信息...\n");
printf("*************************\n");
printf("请输入学生的学号:");
scanf("%d",&save->data.id);
printf("请输入学生的姓名:");
scanf("%s",save->data.name);
printf("请输入学生的性别:");
scanf("%s",save->data.sex);
printf("请输入学生的年龄:");
scanf("%d",&save->data.age);
printf("请输入学生的密码:");
scanf("%s",save->data.password);
printf("请输入学生的所在班级:");
scanf("%d",&save->data.class_number);
printf("请输入学生的语文成绩:");
scanf("%f",&save->data.cscore);
printf("请输入学生的数学成绩:");
scanf("%f",&save->data.mscore);
printf("请输入学生的英语成绩:");
scanf("%f",&save->data.escore);
save->data.total =save->data.cscore + save->data.mscore + save->data.escore;
save->next =pre->next->next;
}
//12.函数功能:根据name 修改结点
//参数列表 :head头结点,name :你要修改的结点的姓名
//函数返回值:void 不需要返回值
void userAmendByName(struct link* head,char* name)
{
if( head == NULL)
{
printf(" head is NULL\n");
return ;
}
//find the pre
struct link* pre = selectByName(head,name);
if(pre == NULL)
{
printf("can not find the node\n");
return ;
}
struct link* save = pre -> next;
printf("*************************\n");
printf("请输入学生的密码:");
scanf("%s",save->data.password);
save->next =pre->next->next;
}
//5,函数功能:根据名次遍历链表打印所有的结点
//参数列表 :head头结点
//函数返回值:void 不需要返回值
void printfAll1(struct link* head)
{
char ch;
int a = 0;
system("clear");
if( head == NULL)
{
printf(" head is NULL\n");
return ;
}
head = head -> next;
printf("名次\t学号\t姓名\t\t性别\t年龄\t密码\t\t班级\t语文\t数学\t英语\t总分\n");
while( head != NULL)
{
printf("%d\t %d\t %s\t\t %s\t %d\t %s\t\t %d\t %.2f\t %.2f\t %.2f\t %.2f\n",a+1,head->data.id,head->data.name,head->data.sex,head->data.age,head->data.password,head->data.class_number,head->data.cscore,head->data.mscore,head->data.escore,head->data.total);
head = head -> next;
a++;
}
printf("以上是全部学员信息!\n");
printf("******************************\n");
printf("按任意键继续~~~\n");
scanf("%c",&ch);
}
//13.1函数功能:根据姓名排序所有结点
//参数列表 :head头结点
//函数返回值:void 不需要返回值
void sortLinkByName(struct link* head)
{
if( NULL == head)
{
printf(" head is null\n");
return ;
}
struct link* save = head -> next;
head = head -> next;
int length = 0;
while(head != NULL)
{
head = head -> next;
length++;
}
int i = 0,j = 0;
for(i = 0;i<length-1;i++)
{
//set head to no1
head = save;
for(j = 0;j<length -i - 1;j++)
{
struct link* agou1 = head;
struct link* agou2 = head->next;
if(agou1->data.name > agou2->data.name)
{
struct student data = agou1->data;
agou1->data = agou2->data;
agou2->data = data;
}
head = head -> next;
}
}
}
//13.2函数功能:根据姓名遍历链表打印所有的结点
//参数列表 :head头结点
//函数返回值:void 不需要返回值
void printfAllByName(struct link* head)
{
char ch;
system("clear");
if( head == NULL)
{
printf(" head is NULL\n");
return ;
}
head = head -> next;
printf("姓名\t\t学号\t性别\t年龄\t密码\t\t 班级\t 语文\t 数学\t 英语\t 总分\t名次\n");
while( head != NULL)
{
printf("%s\t\t %d\t %s\t %d\t %s\t\t %d\t %.2f\t %.2f\t %.2f\t %.2f\t%d\n",head->data.name,head->data.id,head->data.sex,head->data.age,head->data.password,head->data.class_number,head->data.cscore,head->data.mscore,head->data.escore,head->data.total,head->data.rank);
head = head -> next;
}
printf("以上是全部学员信息!\n");
printf("******************************\n");
printf("按任意键继续~~~\n");
scanf("%c",&ch);
}
//14.1函数功能:根据英语成绩排序所有结点
//参数列表 :head头结点
//函数返回值:void 不需要返回值
void sortLinkByEscore(struct link* head)
{
if( NULL == head)
{
printf(" head is null\n");
return ;
}
struct link* save = head -> next;
head = head -> next;
int length = 0;
while(head != NULL)
{
head = head -> next;
length++;
}
int i = 0,j = 0;
for(i = 0;i<length-1;i++)
{
//set head to no1
head = save;
for(j = 0;j<length -i - 1;j++)
{
struct link* agou1 = head;
struct link* agou2 = head->next;
if(agou1->data.escore > agou2->data.escore)
{
struct student data = agou1->data;
agou1->data = agou2->data;
agou2->data = data;
}
head = head -> next;
}
}
}
//14.2函数功能:根据英语成绩遍历链表打印所有的结点
//参数列表 :head头结点
//函数返回值:void 不需要返回值
void printfAllByEscore(struct link* head)
{
char ch;
system("clear");
if( head == NULL)
{
printf(" head is NULL\n");
return ;
}
head = head -> next;
printf("英语\t 姓名\t\t学号\t性别\t年龄\t 密码\t\t 班级\t 语文\t 数学\t 总分\t 名次\n");
while( head != NULL)
{
printf("%.2f\t %s\t\t %d\t %s\t %d\t %s\t\t %d\t %.2f\t %.2f\t %.2f\t%d\n",head->data.escore,head->data.name,head->data.id,head->data.sex,head->data.age,head->data.password,head->data.class_number,head->data.cscore,head->data.mscore,head->data.total,head->data.rank);
head = head -> next;
}
printf("以上是全部学员信息!\n");
printf("******************************\n");
printf("按任意键继续~~~\n");
scanf("%c",&ch);
}
//15.1函数功能:根据名次排序所有结点
//参数列表 :head头结点
//函数返回值:void 不需要返回值
void sortLinkByRank(struct link* head)
{
if( NULL == head)
{
printf(" head is null\n");
return ;
}
struct link* save = head -> next;
head = head -> next;
int length = 0;
while(head != NULL)
{
head = head -> next;
length++;
}
int i = 0,j = 0;
for(i = 0;i<length-1;i++)
{
//set head to no1
head = save;
for(j = 0;j<length -i - 1;j++)
{
struct link* agou1 = head;
struct link* agou2 = head->next;
if(agou1->data.rank > agou2->data.rank)
{
struct student data = agou1->data;
agou1->data = agou2->data;
agou2->data = data;
}
head = head -> next;
}
}
}
//15.2函数功能:根据名次遍历链表打印所有的结点
//参数列表 :head头结点
//函数返回值:void 不需要返回值
void printfAllByRank(struct link* head)
{
char ch;
system("clear");
if( head == NULL)
{
printf(" head is NULL\n");
return ;
}
head = head -> next;
printf("名次\t 姓名\t\t学号\t性别\t年龄\t 密码\t\t 班级\t 语文\t 数学\t 英语\t 总分\n");
while( head != NULL)
{
printf("%d\t %s\t\t %d\t %s\t %d\t %s\t\t %d\t %.2f\t %.2f\t %.2f\t %.2f\n",head->data.rank,head->data.name,head->data.id,head->data.sex,head->data.age,head->data.password,head->data.class_number,head->data.cscore,head->data.mscore,head->data.escore,head->data.total);
head = head -> next;
}
printf("以上是全部学员信息!\n");
printf("******************************\n");
printf("按任意键继续~~~\n");
scanf("%c",&ch);
}
//
#include"std.h"
#include"view.h"
#include"link.h"
#include"control.h"
#include"user.h"
#include"getch.h"
extern struct link* amao_node;
//查看个人信息
void queryUser()
{
while(1)
{
system("clear");
char ch;
/*printf("请输入你想查询的学生姓名:");
char name[20] = {0};
scanf("%s",name);
struct link* pre = selectByName(amao,name);
if(pre == NULL)
{
printf("该姓名不存在!\n");
return ;
}
pre = pre -> next;*/
printf("姓名\t学号\t性别\t年龄\t密码\t班级\t语文\t数学\t英语\t总分\t名次\n");
printf("%s\t %d\t %s\t %d\t %s\t %d\t %.2f\t %.2f\t %.2f\t %.2f\t %d\n",amao_node->data.name,amao_node->data.id,amao_node->data.sex,amao_node->data.age,amao_node->data.password,amao_node->data.class_number,amao_node->data.cscore,amao_node->data.mscore,amao_node->data.escore,amao_node->data.total,amao_node->data.rank);
printf("******************************\n");
printf("是否继续查看个人信息或按任意键返回上一级?(y/n)\n");
while(getchar()!='\n');
scanf("%c",&ch);
if(ch=='y'||ch=='Y')
{
continue;
}else{
return ;
}
}
}
//10.1函数功能:学生账户和密码验证
//参数列表 :无
//函数返回值:void 不需要返回值
void userPassword()
{
int i = 0;
char ppass[20] ={0};
char pname[20] ={0};
for(i=0;i<3;i++)
{
printf("请输入学生账户...\n");
scanf("%s",pname);
struct link* pre = selectByName(amao,pname);
if(strcmp(pre->next->data.name,pname)!=0)
{
printf("您输入的账户名有误,请重新输入...\n");
}else{
amao_node=pre->next;
for(i=0;i<3;i++)
{
printf("请输入密码...\n");
while(getchar()!='\n');
getPassword(ppass);
int i=0;
a:srand((unsigned)time(0));
char yzm[5] = "\0";
char yzm1[5] = "\0";
int length = sizeof(yzm)/sizeof(char);
for(i=0;i<length-1;i++)
{
yzm[i] = random()&+'a';
}
printf("验证码:%s\n",yzm);
printf("请输入验证码:");
scanf("%s",yzm1);
if(strcmp(yzm,yzm1) !=0)
{
printf("验证码输入错误!\n");
goto a;
}else{
if(strcmp(pre->next->data.password,ppass)!=0)
{
printf("输入的账户名和密码有误,请重新输入!\n");
}else{
system("clear");
printf("\n\n");
printf("**********登录成功,欢迎使用!**********\n");
printf("\n\n");
return ;
}
}
}
menu();
}
}
menu();
}
//学生密码修改
void user_password_amend()
{
while(1)
{
char ch;
char name[20] = "";
printf("请输入你想修改的学生姓名\n");
scanf("%s",name);
struct link* pre = selectByName(amao,name);
if(pre == NULL)
{
system("clear");
printf("\n\n");
printf("**********该姓名不存在!**********\n");
printf("\n\n");
sleep(2);
return ;
}
userAmendByName(amao,name);
printf("密码修改成功!\n");
printf("请选择是否继续修改密码或退出?(y/n)\n");
while(getchar()!='\n');
scanf("%c",&ch);
if(ch=='y'||ch=='Y')
{
continue;
}else{
return ;
}
}
}//密码隐藏
#include <sys/stat.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <time.h>
#include <termios.h>
int getch();
void getPassword(char *pcPWD);
int main()
{
printf("请输入密码:");
char temp[20] = "";
getPassword(temp);
printf("\n");
return 0;
}
/*****************************************
* 功能:设置终端为不回显不缓冲,并获取按键的键值
* 返回值:按键的键值int型
* 参数:无参数
****************************************/
int getch()
{
struct termios tm, tm_old;
int fd = STDIN_FILENO, c;
if(tcgetattr(fd, &tm) < 0) //
{
return -1;
}
tm_old = tm;
cfmakeraw(&tm); //就是将终端设置为原始模式,该模式下所有的输入数据以字节为单位被处理。
//在原始模式下,终端是不可回显的,而且所有特定的终端输入/输出模式不可用。
if(tcsetattr(fd, TCSANOW, &tm) < 0) //不等数据传输完毕就立即改变属性 成功返回0 失败-1
{
return -1;
}
c = fgetc(stdin);//
if(tcsetattr(fd, TCSANOW, &tm_old) < 0)
{
return -1;
}
return c;
}
/*****************************************
* 功能:调用getch获取键值保存到pcPWD中并单个回显*
* 可以分别backspace和回车
* 用于获取密码
* 返回值:无返回值
* 参数:字符数组指针pcPWD
****************************************/
void getPassword(char *pcPWD)
{
int ch=0;
int i=0;
for(i=0;i<20;)
{
ch=getch();
if(ch==-1)
{
continue;
}
if((ch == 127 || ch == 8) && i>0)
{
putchar('\b');
putchar(' ');
putchar('\b');
i--;
}
else if(ch==10 || ch == 13)
{
pcPWD[i]=0;
putchar('\n');
return;
}
else if(i==0&&(ch==127 ||ch == 8))
{
printf("\a");
}
else if(i<19)
{
pcPWD[i]=(char)ch;
putchar('*');
i++;
}
else
{
printf("\a");
}
}
}
//主程序
include"std.h"
#include"link.h"
#include"control.h"
#include"view.h"
#include"user.h"
#include"getch.h"
int main(void)
{
amao = calloc(1,sizeof(struct link));
amao -> next = NULL;
load(amao);
menu();
return 0;
}
//最后使用makefile编译程序,完美运行!!!!
bin/student.out:obj/view.o obj/control.o obj/link.o obj/user.o obj/getch.o student_test.c
gcc -o bin/student.out -I./include obj/view.o obj/control.o obj/link.o obj/user.o obj/getch.o student_test.c -Wall -g
obj/view.o:src/view.c
gcc -o obj/view.o -I./include -c src/view.c -Wall -g
obj/control.o:src/control.c
gcc -o obj/control.o -I./include -c src/control.c -Wall -g
obj/link.o:src/link.c
gcc -o obj/link.o -I./include -c src/link.c -Wall -g
obj/user.o:src/user.c
gcc -o obj/user.o -I./include -c src/user.c -Wall -g
obj/getch.o:src/getch.c
gcc -o obj/getch.o -I./include -c src/getch.c -Wall -g