学生管理系统——精简版!

来源:互联网 发布:武装到牙齿的超人软件 编辑:程序博客网 时间:2024/05/02 00:09

/*以下代码只供学习之用*/

 

 

#include<stdio.h>
#include<stdlib.h>
#include<string.h>

#define offsetof(type,member)/
 (size_t)&(((type *)0)->member)     
#define container_of(TYPE, MEMBER, ADDR) /
   (size_t)((size_t)ADDR - offsetof(TYPE, MEMBER))
#define NAME_SIZE 10
#define NUM_SIZE 12

#define CLASS_SIZE 10
typedef struct node node;
typedef struct class class;
struct node {
 struct node *pre;
 struct node *next;
};
struct class{         /*struct of class*/
 char class_name[CLASS_SIZE + 1];
 char class_leader[NAME_SIZE + 1];
 int class_total;
 node student_clink;                          /*manage class'students,link all of the students*/
 node class_clink;                              /*link all the class block*/
};
typedef struct  {                                       /*struct of student*/
 char name[NAME_SIZE + 1];
 char number[NUM_SIZE + 1];
 char sex;
 int chinese_score;
 int math_score;
 int english_score;
 float average_score;
 char class_name[CLASS_SIZE + 1];
    node class_clink;                            /* order by class */
 node student_clink;                        /* order by number */
 node average_clink;         /* order by average_score */        
}student;

node* Search_Student_Number(node *student_head,char number[NUM_SIZE + 1]);
node* Search_Student_Average(node *average_head,float average_score);
void Init_Head( node *head);
void Insert_Node(node *A,node *B);
void Delete_Node(node *p);
int Insert_Student( node *student_head,node *class_head,node *averag_head);
int Delete_Student(node *student_head,node* class_head,char number[NUM_SIZE + 1]);
int Change_Student_Information(node *p ,node*average_head);
int Change_Student(node*student_head,node*average_head,char number[NUM_SIZE + 1]);
node* Search_Class_Name(node* class_head,char* class_name);
int Insert_Class(node *class_head);
int Get_Student(node *student_head,char student_id[NUM_SIZE + 1] );
int Get_All_Students(node*student_head);
int Get_Average(node*average_head);
int Get_Class(node*class_head,char *class_name);

 

/* to search whether  the number is exist */
node* Search_Student_Number(node *student_head,char number[NUM_SIZE + 1])
{
 node *p;
 int flag_exist = 0;
 
 p = student_head->next;
 while(p != student_head) {
  if( strcmp(((student*)((size_t)p - offsetof(student,student_clink)))->number,number) == 0) {
   p = NULL;
   break;
  }
  else  if ( strcmp(((student*)((size_t)p - offsetof(student,student_clink)))->number,number) >0 ){
   break;
  } else {
   p = p->next;
  }
 }
 return p;
}
  
/* to find out the position where the average score is bigger than insert*/
node *Search_Student_Average(node *average_head,float average_score)
{
 node *p;

 p = average_head->next;
 while(p != average_head) {
  if( ((student*)((size_t)p - offsetof(student,average_clink)))->average_score <= average_score) {
   break;
   } else {
   p = p->next;
    }
  }
 return p;
}

/* function of student */  
void Init_Head( node *head)
{
 head->pre = head;
 head->next = head;
}

void Insert_Node(node *A,node *B)  /*Insert A before B*/
{
 A->pre = B->pre;
 A->next = B;
 B->pre->next = A;
 B->pre = A;
}

void Delete_Node(node *p)
{
 p->pre->next = p->next;
 p->next->pre = p->pre;
}

int Insert_Student(node*student_head,node*class_head,node*average_head)
{
    student *p;
    node *temp;
 char name[NAME_SIZE + 1];
 char number[NUM_SIZE + 1];
 char sex;
 int chinese_score;
 int math_score;
 int english_score;
 float average_score;
 char class_name[CLASS_SIZE + 1];
 
    p=(student *)malloc(sizeof(student));
 if(p == NULL) {
  printf("no space enough/n");
  return 0;
 }
 printf("student's class!/n");
 scanf("%s",class_name);
 temp = (node*)Search_Class_Name(class_head,class_name);
 while( temp == NULL) {
  printf("please re_input student's class!/n");
  scanf("%s",class_name);
  temp = (node*)Search_Class_Name(class_head,class_name);
  }  
 strcpy(p->class_name,class_name);
 temp = (node*)((size_t)temp - offsetof(class,class_clink) + offsetof(class,student_clink));

 
 /** 将学生结构体插入该班级链表中**/
 ((class*)((size_t)temp - offsetof(class,student_clink)))->class_total++;
 Insert_Node(&(p->class_clink),temp);
 printf("please input student's student ID/n");
 scanf("%s",number);
 temp = Search_Student_Number(student_head,number);
 while(temp == NULL) {
  printf("please re_input student's student ID/n");
  scanf("%s",number);
  temp = Search_Student_Number(student_head,number);
  } 
 strcpy(p->number,number);
 
 /**将学生结构体插入到整个管理学生信息链表中**/
 Insert_Node(&(p->student_clink),temp);
 printf("please input student's name/n");
 scanf("%s",name);
 strcpy(p->name,name);
 getchar();
 printf("please input student's sex/n");
 scanf("%c",&sex);
 p->sex = sex; 
 printf("please input student's chinese_score/n");
 scanf("%d",&chinese_score);
 p->chinese_score=chinese_score;
 printf("please input student's english_score/n");
 scanf("%d",&english_score);
 p->english_score=english_score;
 printf("please input student's math_score/n");
 scanf("%d",&math_score);
 p->math_score=math_score;
 average_score = (float)((chinese_score + english_score + math_score)/3.0);
 p->average_score = average_score;
 temp = Search_Student_Average(average_head, average_score); 

 /**将学生结构体插入按平均分排名的链表中**/
    Insert_Node(&(p->average_clink),temp); 

 
     return 1;
}


int Delete_Student(node *student_head,node * class_head,char number[NUM_SIZE + 1])  // 缺少另一个链表的删除;
{
 node *p;
 node *p_temp;
 char class_name[NAME_SIZE + 1];

 p = student_head->next;
 if(p == student_head) {
  printf("it's clear/n");
  return 0;
    } else {
  while(p != student_head) {
   if( strcmp(((student*)((size_t)p - offsetof(student,student_clink)))->number,number) == 0) {

    /*删除与所有学生相连节点*/
    Delete_Node( p);

    /*删除与班级相连节点*/
    Delete_Node((node *)((size_t)p - offsetof(student,student_clink) + offsetof(student,class_clink)));
    
    /*找到所在班级节点并修改人数*/
    strcpy(class_name ,((student*)((size_t)p - offsetof(student,student_clink)))->class_name);
    p_temp = Search_Class_Name(class_head,class_name);
    ((class *)((size_t)p_temp - offsetof(class,class_clink)))->class_total--;

    /*删除平均成绩相连节点*/
    Delete_Node((node *)((size_t)p - offsetof(student,student_clink) + offsetof(student,average_clink)));

    

    printf("Delete Success!/n");
    break;
    } else {
            p = p->next;
    }
  } 
  if(p == NULL) {
   return 0;
  } else {  
   return 1;
  }
 }
}

int Change_Student_Information(node *p ,node*average_head)
{
 int option;
 int score;
 node *average_p;
 student *p_temp;

 p_temp = ((student *)container_of(student,student_clink,p));
 while(1) {
  printf("/t*****************************/n");
  printf("/t* 0: quit!                  */n");
  printf("/t* 1: change chinese_score!  */n");
  printf("/t* 2: change english_score!  */n");
  printf("/t* 3: change math_score!     */n");
  printf("/t*****************************/n");
  scanf("%d",&option);
  switch(option)
  {
     case 0:   return 0;
  case 1:   scanf("%d",&score);
     p_temp->chinese_score = score;
       break;
  case 2:    scanf("%d",&score);
     p_temp->english_score = score;
       break;
  case 3:    scanf("%d",&score);
     p_temp->math_score = score;
       break;
  default:  printf("no this kind of change!/n");
      return 0;
  }
  p_temp->average_score = (float)((p_temp->chinese_score + p_temp->english_score + p_temp->math_score)/3.0);
  Delete_Node(&(p_temp->average_clink));
  average_p = Search_Student_Average(average_head,p_temp->average_score);
  Insert_Node(&(p_temp->average_clink),average_p);
  
 }

}
 
/* 修改学生信心函数 */ 
int Change_Student(node*student_head,node*average_head,char number[NUM_SIZE + 1])
{
 node *p;
 p = student_head->next;
 if(p == student_head) {
  printf("it's clear/n");
  return 0;
 } else {
  while(p != student_head) {
   if( strcmp(((student*)((size_t)p - offsetof(student,student_clink)))->number,number) == 0) {
     Change_Student_Information(p,average_head);
    break;
          } else {
           p = p->next;
   }
  }
  if(p == NULL) {
   return 1;
  } else {
   return 0;
  }
 }
}

 

/************************************************************************/

/* 找出class 中是否有这个名字*/
/* 存在返回节点地址,不存在返回NULL*/
node* Search_Class_Name(node* class_head,char* class_name)     
{
 node *p;
 
 p = class_head->next;
 while(p != class_head) {
  if( strcmp(((class *)((size_t)p - offsetof(class,class_clink)))->class_name,class_name) == 0) {
   break;
   } else {
    p = p->next;
  }
 }
 if(p == class_head) {
  p = NULL;
 }
 return p;
}

/* 插入class 成员*/
int Insert_Class(node *class_head)
{
 class *p;
 char class_name[NAME_SIZE + 1];
 char class_leader[NAME_SIZE + 1];

 p = (class *)malloc(sizeof(class));
 if(p == NULL) {
  printf("memery erro!/n");
  return 0;
  } 
  printf("please input class_name!/n");
  scanf("%s",class_name);
  while(Search_Class_Name(class_head,class_name) != 0) {
   printf("please RE_input class_name!/n");
   scanf("%s",class_name);
   }
  strcpy(p->class_name,class_name);
  printf("input class_leader!/n");
  scanf("%s",class_leader);
  strcpy(p->class_leader,class_leader);
  p->class_total = 0;
  Insert_Node(&(p->class_clink),class_head);
  Init_Head(&(p->student_clink));
  return  1;
}

/*  根据学号查询信息*/
int Get_Student(node *student_head,char student_id[NUM_SIZE + 1] )
{
 node *p;
 student *q;
 
 p = student_head->next;
 if(p == student_head) {
  printf("there's no data to get out/n");
  return 0;
 }
 
 while(p != student_head) {
  q = (student *)((size_t)p - offsetof(student,student_clink));
  if( strcmp(q->number,student_id) == 0) {
   printf("class'sname/tstudent'sname/tnumber/tsex/tchinese/tenglist/tmath/taverage/n");
   printf("%s/t%s/t%s/t/t%c/t%d/t%d/t%d/t%.2f/n",q->class_name,q->name,q->number,q->sex,/
   q->chinese_score,q->english_score,q->math_score,q->average_score);
   break;
  } else {
   p = p->next;
   }
 }
 return 1;
}

/*根据学生链表显示所有学生信息*/
int Get_All_Students(node*student_head)
{
 node *p;
 student *q;

 p = student_head->next;
 printf("name/t number/t sex/t Chinese/t English/t Math/t average/n");
 while(p != student_head) {
  q = (student *)((size_t)p - offsetof(student,student_clink));
  printf("%s/t%s/t%s/t/t%c/t%d/t%d/t%d/t%.2f/n",q->class_name,q->name,q->number,q->sex,/
    q->chinese_score,q->english_score,q->math_score,q->average_score);
  p = p->next;
  }
 printf("show all of the students' information!/n");
 return 1;
}

/* 根据平均成绩排序输出 */
int Get_Average(node*average_head)
{
 node *p;
 student *q;

 p = average_head->next;
 printf("class's name/t student's name/tnumber/tsex/tchinese/tenglist/tmath/taverage/n");
 while(p != average_head) {
  q = (student *)((size_t)p - offsetof(student,average_clink));
  printf("%s/t%s/t%s/t/t%c/t%d/t%d/t%d/t%.2f/n",q->class_name,q->name,q->number,q->sex,/
    q->chinese_score,q->english_score,q->math_score,q->average_score);
  p = p->next;
  }
 printf("show all of the students' information!/n");
 return 1;
}

int Get_Class(node*class_head,char *class_name)
{
 node *p;
 student *q;
 class *p_temp;

 p = class_head->next;
 while(p != class_head) {
  p_temp = (class*)(container_of(class,class_clink,p));
  if( strcmp(p_temp->class_name,class_name) == 0 ) {
   printf("class_name/tclass_leader_name/tclass_total/n");
   printf("%s/t%s/t%d/n",p_temp->class_name,p_temp->class_leader,p_temp->class_total);
   p = p_temp->student_clink.next;
   printf("name/tnumber/tsex/tchinese/tenglist/tmath/taverage/n");
   while(p != &(p_temp->student_clink) ) {    
    q = (student *)((size_t)p - offsetof(student,class_clink));   
    printf("%s/t%s/t%s/t/t%c/t%d/t%d/t%d/t%.2f/n",q->class_name,q->name,q->number,q->sex,/
    q->chinese_score,q->english_score,q->math_score,q->average_score);
    p = p->next;
    }
   printf("show all of the students' information!/n");
   return 1;;
   }
  p = p->next;
 }
 printf("no students' information!/n");
 return 1;
}


/***********************************************************************/
int main()
{
 node class_head;
    node student_head; 
 node average_head;
 node *temp;
 char class_name[NAME_SIZE + 1];
 int option;
 char student_id[NUM_SIZE + 1];

 Init_Head(&class_head);
    Init_Head(&student_head);
 Init_Head(&average_head);
 while(1) {
  printf("/t**************************************************************/n");
  printf("/t* 0: exit!                                                   */n");
  printf("/t* 1: insert class!                                           */n");
  printf("/t* 2: insert student!                                         */n");
  printf("/t* 3: change information!                                     */n");
  printf("/t* 4: delete student!                                         */n");
  printf("/t* 5: display all of student's information by class!          */n");
  printf("/t* 6: display all of student's information by number!         */n");
  printf("/t* 7: display all of student's information by average score!  */n");
  printf("/t* 8: display student's information ,input his ID             */n");
  printf("/t**************************************************************/n");
  printf("which kind of operation you want to operate!/n");
  scanf("%d",&option);
  switch(option)
  {
  case 0: printf("have been quit!/n");
       return 0;
  case 1: Insert_Class(&class_head);
        break;
  case 2: Insert_Student(&student_head,&class_head,&average_head);
       break;
  case 3: printf("please input which student's information you need to change!/n");
        scanf("%s",student_id);
        Change_Student(&student_head,&average_head,student_id);
        break;
  case 4: printf("please input which student's information you need to delete!/n");
         scanf("%s",student_id);
         Delete_Student(&student_head,&class_head,student_id);
         break;
  case 5: printf("please input which class'information you want to display!/n");
       scanf("%s",class_name);
    temp = (node*)Search_Class_Name(&class_head,class_name);
       while( temp == NULL) {
         printf("please re_input which class'information you want to display!/n");
           scanf("%s",class_name); 
      temp = (node*)Search_Class_Name(&class_head,class_name);
          }
    Get_Class(&class_head,class_name);
    break;
     
  case 6: Get_All_Students(&student_head);        
    break;
  case 7: Get_Average(&average_head);
         break;
  case 8:  printf("please input student's number!/n");
    scanf("%s",student_id);
    while( Search_Student_Number(&student_head,student_id) == NULL) {
     printf("please re_input student's number!/n");
     scanf("%s",student_id);
    }
     Get_Student(&student_head,student_id);
    break;
  default:
       printf("erro!/n");
    return 0;
  }

    return 1;
}
  

 

 

 

原创粉丝点击