题目要求
1:要求有登陆功能
2:成员信息:学号,语数外成绩,账号,密码,性别,身份(老师还是学生),以及地址
3:老师和学生都可以修改自己的密码
4:老师可以增加或者删除学生
5:学生只可以查看自己的成绩
6:老师可以查看所有学生的成绩,以及修改本科的成绩
#include<stdio.h>
#include<stdlib.h>
#include<stdbool.h>
#include<string.h>
typedef struct node
{
int id_num;//teacher or student's number
char status;//teacher : t , student : s
int chinese;
int math;
int English;
int passwd;
char address[64];
char sex;//man : m , women : w
struct node *next;
}*listnode;
listnode listnode_init()
{
listnode head = malloc(sizeof(struct node)); //申请头结点空间
if(head == NULL)
{
perror("list init error");
return NULL;
}
head->next = NULL;
return head;//返回头结点地址
}
void data_init(listnode newnode ,int id_num,char status,int chinese,int math ,int English , int passwd,char * address,char sex)
{
newnode->id_num = id_num;
newnode->status = status;
newnode->chinese = chinese;
newnode->math = math;
newnode->English = English;
newnode->passwd = passwd;
strcpy(newnode->address,address);
newnode->sex = sex;
}
bool add_node(listnode head,int id_num,char status,int chinese,int math ,int English , int passwd,char * address,char sex)
{
listnode newnode = malloc(sizeof(struct node));
if(newnode == NULL)
{
perror("malloc newnode error");
return -1;
}
//2、初始化节点数据
data_init(newnode ,id_num,status,chinese,math ,English,passwd,address,sex);
//3找到链表尾部
listnode p = head;
while(p->next != NULL) //如果p->next不等于 NULL,证明后面还有节点
{
p = p->next;
}
newnode->next = p->next;
p->next = newnode;
printf("尾插法所接入的数据 %d,%c\n", p->next->id_num,p->next->status);
return 0;
}
listnode search_member_prev(listnode head ,int id_number)
{
listnode tmp = head ;
while(tmp->next != NULL)
{
if(tmp->next->id_num == id_number)
{
return tmp ;
}
tmp = tmp->next;
}
return NULL;
}
//传入头节点,和另一个节点
//函数中输入 id_num 和 passwd,若匹配,返回true
listnode login_in(listnode head,listnode newOne)
{
int passwdInput,id_num;
listnode new = head;
printf("please input your id_num(five Number): ");
if(scanf("%d",&(id_num)) == 1)
{
while(getchar() != '\n');
listnode tmp = search_member_prev(head,id_num);
if(tmp != NULL)
{
printf("please input your password :");
scanf("%d",&passwdInput);
while(getchar() != '\n');
if(tmp->next->passwd == passwdInput)
{
newOne = tmp;
return newOne;
}
}
}
return NULL;
}
int JudgeStuTea(listnode head ,listnode newOne)
{
printf("1");
int number = newOne->next->id_num ;
listnode tmp = search_member_prev(head,number);
if( tmp->next->status == 't')
{
printf("this is a teacher\n");
return 1;
}
else
return 0;
}
void show_grade(listnode newOne)
{
printf(" %d \n", newOne->next->id_num);
printf(" chinese : %d\n",newOne->next->chinese);
printf(" math : %d\n",newOne->next->math);
printf(" English : %d\n\n",newOne->next->English);
}
//修改密码
bool alter_passwd(listnode newOne)
{
char Judge;
int passwd;
printf("your password : %d\n",newOne->next->passwd);
printf("You are sure about changing Your pasword ? y/n : \n");
scanf("%c",&Judge);
while(getchar()!='\n');
if(Judge == 'y')
{
printf("please input your new password :\n");
scanf("%d",&passwd);
newOne->next->passwd = passwd;
printf("%d\n",newOne->next->passwd);
return true;
}
else
{
printf("don't waste my time , bitch !\n");
return false;
}
}
//学生操作
void StuMove(listnode head , listnode newOne)
{
int numberOption;
while(1)
{
printf(" hello ,%d \n",newOne->next->id_num);
printf(" press 0 : show your all grade \n\n");
printf(" press 1 : alter your passwd \n\n\n");
printf(" press 2 : exit\n\n");
printf(" Your option : \n");
scanf("%d",&numberOption);
while(getchar() != '\n');
switch(numberOption)
{
case 0:
show_grade(newOne);
break;
case 1:
alter_passwd(newOne);
break;
case 2:
return;
}
}
}
//打印所有的成员信息
void show_all(listnode head)
{
listnode tmp = head;
while(tmp->next != NULL)
{
printf("\tI\tS\tC\tM\tE\tA\t\tSEX\n\n");
printf("\t%d\t%c\t%d\t%d\t%d\t%s\t%c\t\n\n",tmp->next->id_num,tmp->next->status,tmp->next->chinese,tmp->next->math ,tmp->next->English ,tmp->next->address,tmp->next->sex);
tmp = tmp->next;
}
}
listnode add_grades(listnode head)
{
listnode tmp = head;
char addressInput[20];
while(tmp->next != NULL)
{
tmp = tmp->next;
}
listnode new = malloc(sizeof(struct node));
printf("\n\n");
printf("please input the student 's id : ");
scanf("%d",&(new->id_num));
while(getchar() != '\n');
printf("\n\n");
new->status = 's';
printf("please input the student 's chinese : ");
scanf("%d",&(new->id_num));
while(getchar() != '\n');
printf("\n\n");
printf("please input the student 's math : ");
scanf("%d",&(new->math));
while(getchar() != '\n');
printf("\n\n");
printf("please input the student 's English : ");
scanf("%d",&(new->English));
while(getchar() != '\n');
printf("\n\n");
printf("please input the student 's passwd : ");
scanf("%d",&(new->passwd));
while(getchar() != '\n');
printf("\n\n");
printf("please input the student 's address : ");
gets(addressInput);
strcpy(new->address,addressInput);
printf("\n\n");
printf("please input the student 's sex : ");
scanf("%c",&(new->sex));
while(getchar() != '\n');
tmp->next = new;
show_all(head);
return head;
}
//修改学生信息
bool alter_grades(listnode head,listnode newOne)
{
int id_num,grade,subject,judgeStu,teaSubject = 0;
printf("please input the student's id_num :");
scanf("%d",&id_num);
while(getchar() != '\n');
listnode tmp = search_member_prev(head ,id_num);
//根据id_num在学生列表中匹配学生,若匹配成功,且该id_num不是一个老师 tmp->next->status != 't'
//则进行下一步操作
if( ( tmp != NULL ) && (tmp->next->status != 't'))
{
printf("is he this guy ?(y:1,n:0)\n");
show_grade(tmp);
scanf("%d",&judgeStu);
while(getchar()!='\n');
if(judgeStu == 1)
{
//这里匹配登陆账号老师是教哪一科的,从而修改具体学生哪一科的成绩
if(newOne->next->math == -1)
{
printf(" how much about math : ");
scanf("%d",&(tmp->next->math));
show_grade(tmp);
return true;
}
else
if(newOne->next->chinese == -1)
{
printf(" how much about chinese : ");
scanf("%d",&(tmp->next->chinese));
show_grade(tmp);
return true;
}
else
if(newOne->next->English == -1)
{
printf(" how much about English : ");
scanf("%d",&(tmp->next->English));
show_grade(tmp);
return true;
}
}
}
return false;
}
//学生删除操作 参数:一个listnode 的头节点
void student_delete(listnode head)
{
int id_number,judgeStu;
listnode tmp = head;
listnode disap;
printf("who , delete :");
scanf("%d",&id_number);
//根据输入寻找学生,
tmp = search_member_prev(head ,id_number);
if(tmp != NULL)
{
printf("is he this guy ?(y:1,n:0)\n");
show_grade(tmp);
scanf("%d",&judgeStu);
if(judgeStu == 1)
{
disap = tmp->next;
tmp->next = tmp->next->next;
free(disap);
show_all(head);
printf("delete student successfully");
}
else
{
printf("delete failed");
}
}
}
//老师操作选项
//根据输入选择老师可以进行的功能
void TeaMove(listnode head,listnode newOne)
{
int options;
while(1)
{
printf(" welcome , %d",newOne->next->id_num);
printf(" press 0 : change your passwd\n");
printf(" press 1 : show the all grades\n");
printf(" press 2 : alter one student's grades\n");
printf(" press 3 : delete one student\n");
printf(" press 4 : add one student\n");
printf(" press 5 : exit\n\n");
scanf("%d",&options);
while(getchar()!= '\n');
switch(options)
{
case 0:
alter_passwd(newOne);
break;
case 1:
show_all(head);
break;
case 2:
alter_grades(head,newOne);
break;
case 3:
student_delete(head);
break;
case 4:
head = add_grades(head);
break;
case 5:
return;
}
}
}
int main()
{
//先插入几个学生和老师的信息
listnode head = listnode_init();
add_node(head,20161,'t',-1,0,0,123456,"hubeijinghzou",'w');
add_node(head,20162,'t',0,-1,0,123457,"hubeiwuhan",'m');
add_node(head,20163,'t',0,0,-1,123458,"hubeixiaogan",'m');
add_node(head,20164,'s',59,60,61,123459,"hubeijingzhou",'w');
add_node(head,20165,'s',79,73,77,123450,"hubeijingzhou",'m');
add_node(head,20166,'s',99,83,87,223450,"hubeijingzhou",'m');
//验证登陆信息
listnode newOne = head->next;
while(1)
{
newOne = login_in(head,newOne);
if(newOne != NULL)
break;
}
//欢迎界面
printf("welcome to zhangke's school info manage system :\n\n");
//进行判断,如果是老师,进入 TeaMove
//如果是学生,进入StuMove
if( JudgeStuTea(head,newOne) == 1 )
TeaMove(head,newOne);
else
StuMove(head,newOne);
}
思路:
1 登陆:我们需要实现登陆功能,我的做法是程序运行时,我先初始化链表,然后插入几个成员信息,包括学生和老师的,(这在主函数的 add_node中可以看到插入了6个成员),你也可以改变思路:初始化链表之后,先进行 add_grades() (即添加成员,再进行登陆程序),
2 老师:在老师的设定上,我采取了这样的方法,老师没有语数外成绩,教哪一科就将哪一科的成绩设定为-1,登陆监测到是老师就进行Tea_move,然后一个死循环,中间加switch(),对输入的功能选项进行选择,这里,老师查看成绩时,调用的是show_all
3 学生没什么好说的,只有查看成绩时,调用show_grades
4,链表这一块,掌握最基本的增删改查就可以了,然后进行一些练习,在调试程序的时候多加一些priintf();才能更好的查看错误以及程序的运行情况,否则,程序运行报错只有一个段错误,真的惨