• 学生管理系统


    /*
     学生信息管理系统
    需求分析
    1.    创建学生学生记录信息链表。
    2.    输出全部学生信息
    3.    查询学生信息记录(按姓名) 
    4.    删除学生信息记录(按姓名)
    5.    按总成绩来排序
    6.    插入记录
    7.    保存记录到文件中
    8.  打开文件读取学生记录  
    9.  删除全部学生记录
    10. 退出系统
    */
    
    #include <iostream>
    #include <string>
    #include <fstream>
    #define lEN  sizeof(STUDENT)
    using namespace std;
    
    typedef struct stu     /*定义结构体数组用于缓存数据*/
    {
        int num;
        string name;
        //char name[20];
        int score[3];
        int sum;
        float average;
        int order;
        stu *next;
    }STUDENT;
    
    //函数声明
    int         menu_select();     /*菜单函数*/
    STUDENT  *create_List();     /*创建链表*/
    void print_List(STUDENT * head);     /* 显示全部记录*/
    void search_STUDENT(STUDENT * head,string name);      /*按名字查找记录*/
    void search_STUDENT(STUDENT * head); /*查找记录*/
    STUDENT * delete_STUDENT(STUDENT * head);     /*删除记录*/
    STUDENT * delete_List(STUDENT * head);   //删除链表
    STUDENT *sort_List(STUDENT * head);      /*排序*/
    STUDENT *insert_STUDENT(STUDENT * head,STUDENT * S);     /*插入某一记录*/
    STUDENT *insert_STUDENT(STUDENT * head);     /*插入记录*/
    void save_toFile(STUDENT *head);       /*保存文件*/
    STUDENT *load_from_File();          /*读文件*/
    void exit_system(); //退出系统
    
    int count=0;
    int main()
    {
        //menu_select();
        
        STUDENT *head=NULL;
        
        for(;;)
        {
            switch(menu_select())
            {
            case 1: head=create_List();break; //1.新创建学生记录
            case 2: print_List(head);break;   //2.打印学生记录
            case 3: search_STUDENT(head);break; //3.查询学生记录
            case 4: head=delete_STUDENT(head);break;  //4.删除学生记录
            case 5: head=sort_List(head);break; //5.排序
            case 6: head=insert_STUDENT(head);break; //6.插入记录
            case 7: save_toFile(head);break; //7.保存文件
            case 8: head=load_from_File();break; //8.保存文件
            case 9: head=delete_List(head) ;break; //9.删除全部学生记录(链表)
            case 10: exit_system() ;break; //10.退出系统    
          }
        }
        /*
        head=create_List(); //创建链表
        print_List(head); //遍历链表    
       */
        /*
        string search_name;
        cout<<"
    输入您要查找的学生姓名: ";
        cin>>search_name;
        search_STUDENT( head,search_name); //按姓名进行查找
        */
        /*
        STUDENT *s=new STUDENT;
        cout<<"输入要插入的学生信息"<<endl;
        cout<<"学号     姓名    数学成绩      语文成绩    英语成绩 "<<endl;
        cin>>s->num>>s->name>>s->score[0]>>s->score[1]>>s->score[2];
        s->sum=s->score[0]+s->score[1]+s->score[2];
        s->average=(float)s->sum/3;
        s->order=count+1;
        s->next=NULL;
        head=insert_STUDENT( head,s);  //插入节点后头指针可能会改变
        print_List(head);
        
    
        cout<<"按照总成绩排序后"<<endl;
        head=sort_List(head); //排序
        print_List(head);
        
       
        head=delete_STUDENT(head);
        print_List(head); //遍历链表
    
        //删除后重新排序,此时记录中的order会发生改变,为当前记录集的排序序号
        head=sort_List(head); //排序 
        print_List(head); //遍历链表
       */
        /*
        save_toFile(head); //保存到文件
    
    
        //head=delete_List(head); //删除整个链表
    
        head=load_from_File() ; //读入链表
        print_List(head); //遍历链表
        */
        return 0;
    }
    
    
    int     menu_select()    /*菜单函数*/
    {
        int choice;
        cout<<"
    		学生管理系统菜单选择"<<endl;
        cout<<"***************************************************"<<endl<<endl;
        cout<<"		1.输入学生记录"<<endl;
        cout<<"		2.打印学生记录"<<endl;
        cout<<"		3.按姓名查找学生记录"<<endl;
        cout<<"		4.按姓名删除记录"<<endl;
        cout<<"		5.排序"<<endl;
        cout<<"		6.插入记录"<<endl;
        cout<<"		7.保存文件"<<endl;
        cout<<"		8.加载文件"<<endl;
        cout<<"		9.删除全部学生记录"<<endl;
        cout<<"		10.退出系统"<<endl;
        cout<<"***************************************************"<<endl<<endl;
        cout<<"输入你的选择1~10: ";
        cin>>choice;
        while(choice<1||choice>10)
        {
            cout<<"您输入的选项有误,请重新输入: ";
            cin>>choice;
        }
        return choice;
    }
    
    
    
    STUDENT  *create_List()    //创建链表
    {   cout<<"开始输入用户信息(输入的x学号为0或小于0退出):"<<endl;
        STUDENT * head=NULL;  //链表头节点
        STUDENT * p=NULL; 
        //int  count=0; //记录要创建的链表节点个数
        STUDENT * s=new STUDENT;
        cout<<"学号     姓名    数学成绩      语文成绩    英语成绩 "<<endl;
        cin>>s->num>>s->name>>s->score[0]>>s->score[1]>>s->score[2];
        s->next=NULL;
        while(s->num>0)
        {
            s->sum=s->score[0]+s->score[1]+s->score[2];
            s->average=(float)s->sum/3;
            s->order=count+1;
            if(head==NULL) //如果是第一个节点
            { head=s;
              p=s; //p指向当前链表中的最后一个节点
            }
            else  //如果不是第一个节点
            {
                p->next=s;
                p=s; //p指向当前链表中的最后一个节点
             }        
            count++;
            s=new STUDENT;
             cin>>s->num>>s->name>>s->score[0]>>s->score[1]>>s->score[2];
            s->next=NULL;
        }
        delete s;
        cout<<count<<"条学生记录建立成功"<<endl<<endl;
        return head;
    
    }
    
    
    
    void print_List(STUDENT * head)    //显示全部记录
    {
        STUDENT * p=head;
        int rec=1;
        if(head==NULL)  //判断是否为空链表
        { 
            cout<<"当前学生信息记录条数为0!"<<endl;
            return ;  
        }
        cout<<"记录号   学号     姓名    数学成绩      语文成绩    英语成绩   总成绩   平均成绩  排序号"<<endl;
        while(p->next!=NULL)  //遍历链表,输出各个节点数据
        {  
            cout<<rec<<" "<<p->num<<" "<<p->name<<" "<<p->score[0]<<" "
                <<p->score[1]<<" "<<p->score[2]<<" "<<p->sum<<" "<<p->average<<" "<<p->order<<endl; 
             p=p->next;
             rec++;
        }
        cout<<rec<<" "<<p->num<<" "<<p->name<<" "<<p->score[0]<<" "
                <<p->score[1]<<" "<<p->score[2]<<" "<<p->sum<<" "<<p->average<<" "<<p->order<<endl;
    }
    
    
    STUDENT *delete_STUDENT(STUDENT * head)    //删除记录
    {
       STUDENT *p=head;
       STUDENT *q=head;
       cout<<"请输入您要删除的学生姓名 :";
       string name;
       cin>>name;
       int rec=0;
       while(p!=NULL)
       {  
          if(p->name!=name)
          {   
              q=p;//q为p之前的节点
              p=p->next;
          }
          else
          {
              if(p==head)//删除的节点在链表头部
              {
                  head=head->next;
                  delete p;
                  rec++;
                  count--; //链表个数减少一个
                  p=head;
               }
              else  //删除的节点不在链表头部
              {
                  q->next=p->next;
                  delete p;
                  rec++;
                  count--; //链表个数减少一个
                  p=q->next;
              }
          }
      }    
       cout<<"已删除 "<<rec<<""<<"姓名是 "<<name<<" 的记录!"<<endl<<endl;
       return head;    
    }
    
    
    
    
    
    STUDENT *insert_STUDENT(STUDENT * head,STUDENT * s)    //插入记录//插入一个节点,s指向要插入的节点,找到比s数据大的节点前插入
    {
        
        STUDENT * p=NULL; //指向要插入的节点位置
        STUDENT * q=NULL; //指向要插入的节点位置的前一个位置
        
        p=head;
        if(head==NULL)
            head=s;
        else
        {
            if (s->sum<p->sum) //要插入的节点比头节点数据还小(总成绩)
            {
                s->next=p;
                head=s;
            }
            else 
            {
                while(s->sum>p->sum&&p->next!=NULL)
                { 
                    q=p;
                    p=p->next;
                }
                if(p->next!=NULL)
                {
                    s->next=p;
                    q->next=s;
                }
                if(p->next==NULL)
                {
                    if(s->sum>p->sum)
                        p->next=s;
                    else
                    {
                        s->next=p;
                        q->next=s;
                    }
                }
            }        
        }
        count++; //链表个数增加一个
        //cout<<"insert a STUDENT successful!"<<endl<<endl;    
        return head;
    }
    
    STUDENT *insert_STUDENT(STUDENT * head)    /*插入记录*/
    {
        STUDENT *s=new STUDENT;
        cout<<"输入要插入的学生信息"<<endl;
        cout<<"学号     姓名    数学成绩      语文成绩    英语成绩 "<<endl;
        cin>>s->num>>s->name>>s->score[0]>>s->score[1]>>s->score[2];
        s->sum=s->score[0]+s->score[1]+s->score[2];
        s->average=(float)s->sum/3;
        s->order=count+1;
        s->next=NULL;
        head=insert_STUDENT( head,s);  //插入节点后头指针可能会改变
        cout<<"插入记录成功!"<<endl;
        return head;
    }
    
    //排序思路
    //将无序链表从第一个节点开始依次插入到一个开始为空的空链表上(插入函数要先找到要插入的位置)
    STUDENT *sort_List(STUDENT * head)  //链表排序
    {     
        STUDENT  * head_sort=NULL;
        if(head==NULL)
            return head;
        STUDENT * p;
        while(head!=NULL) //排序
        {   
            p=head;  //将p指向的节点从原链表中删除
            head=head->next; //原链表头节点后移
            p->next=NULL; //将p与原链表中的下一个节点断开
            head_sort=insert_STUDENT(head_sort,p);
        }
        //排序完要对链表中的节点order成员进行修改
        p=head_sort;
        int order=1;
        while(p!=NULL)
        {
           p->order=order;
           order++;
           p=p->next;
        }
        cout<<"排序完成!"<<endl;
        return head_sort;
    }
    
    
    void search_STUDENT(STUDENT * head,string name)     //查找记录,按姓名查找
    {
           STUDENT * p=head;
        bool flag=0; //作为是否找到的标记
        if(head==NULL)  //判断是否为空链表
        { 
            cout<<"the list is empty! "<<endl;
            return ;  
        }
        while(p!=NULL)  //遍历链表,输出各个节点数据
        {  
            if (p->name==name)
            {
                flag=1; 
                cout<<"您查找的姓名为 "<<name<<" 的用户存在,具体记录信息如下:"<<endl;
                cout<<" "<<p->num<<" "<<p->name<<" "<<p->score[0]<<" "
                    <<p->score[1]<<" "<<p->score[2]<<" "<<p->sum<<" "<<p->average<<" "<<p->order<<endl;             
            }    
            p=p->next;
        }
        if(flag==0)
        {
          cout<<"您查找的姓名为 "<<name<<" 的用户不存在!"<<endl;
        }
    }
    
    void search_STUDENT(STUDENT * head) /*查找记录*/
    {
        string search_name;
        cout<<"
    输入您要查找的学生姓名: ";
        cin>>search_name;
        search_STUDENT( head,search_name); //按姓名进行查找
    }
    
    
    
    STUDENT * delete_List(STUDENT * head)   //删除链表
    {   
        int count=0;
        if(head==NULL)
        {
            cout<<"the list is empty ,no STUDENT to delete!"<<endl;
            return head;
        }
        STUDENT * p;
        while(head!=NULL)
        {
            p=head;
            head=head->next;
            delete p;
            count++;
        }
        cout<<"整个链表删除完成,已删除掉"<<count<<"个链表节点!"<<endl<<endl;
        ::count-=count;
        return head;
    }
    
    
    void save_toFile(STUDENT *head)       //保存文件
    {
        ofstream outfile("student.out",ios::binary);
        if(!outfile)
        { 
            cout<<"打开保存文件失败!";
            return;      
        }
        STUDENT * p=head;
        int rec=0;
        while(p!=NULL)
        {  rec++;
           outfile.write((char *)p,lEN);
           p=p->next;      
        }
        cout<<"文件保存成功!"<<rec<<" 条记录被保存"<<endl;
        outfile.close();
    }
    
    
    
    STUDENT * load_from_File()         //读文件
    {
        ifstream infile("student.out",ios::binary);
        if(!infile)
        { 
            cout<<"打开读入文件失败!";
            return NULL;      
        }
        int rec=0;
        STUDENT * head=NULL;
        STUDENT *p=NULL;
        STUDENT *s=NULL;
        //while(!infile.eof())  //如果此处用eof函数判断文件结尾时,会多读取一条记录。因为eof要先读取出EOF后再下一次返回真
        while(!(infile.peek()==EOF))  //用peek函数去监读取是否到文件结束EOF
        {  s=new STUDENT;
           infile.read((char *)s,lEN);
           s->next=NULL;
           if(head==NULL) //如果是第一个节点
           { head=s;
             p=s; //p指向当前链表中的最后一个节点
             rec++;
           }
           else  //如果不是第一个节点
           {
               p->next=s;
               p=s; //p指向当前链表中的最后一个节点
               rec++;
            }        
        }
        cout<<"
    文件读取成功!"<<rec<<" 条记录被读取"<<endl;
        infile.close();
        return head;
    }
    
    
    void exit_system() //退出系统
    {
       cout<<"退出系统..."<<endl;
       exit(0);
    }
     

    -----------------------------------------------------------------------------

    注意:一下函数中的红色部分

    STUDENT * load_from_File()         //读文件
    {
    ifstream infile("student.out",ios::binary);
    if(!infile)
    { 
    cout<<"打开读入文件失败!";
    return NULL;   
    }
        int rec=0;
        STUDENT * head=NULL;
        STUDENT *p=NULL;
        STUDENT *s=NULL;
    //while(!infile.eof())  //如果此处用eof函数判断文件结尾时,会多读取一条记录。因为eof要先读取出EOF后再下一次返回真
    while(!(infile.peek()==EOF))  //用peek函数去监读取是否到文件结束EOF
    {  s=new STUDENT;
       infile.read((char *)s,lEN);
       s->next=NULL;
       if(head==NULL) //如果是第一个节点
       { head=s;
         p=s; //p指向当前链表中的最后一个节点
    rec++;
       }
       else  //如果不是第一个节点
       {
       p->next=s;
       p=s; //p指向当前链表中的最后一个节点
       rec++;
        } 
    }
    cout<<"
    文件读取成功!"<<rec<<" 条记录被读取"<<endl;
    infile.close();
    return head;
    }
    

    相关的理解可以参考 

    C++ eof()函数相关应用技巧分享

  • 相关阅读:
    云计算和SOA何时走到了一起?
    MVP
    Mvp
    Technology Radar of thoughtworks
    JSF
    我们要积极学习互联网的用户体验
    Gwt
    数字的字符串处理
    C语言字符串函数大全(转自百度百科)
    树状数组
  • 原文地址:https://www.cnblogs.com/beautiful-code/p/5239307.html
Copyright © 2020-2023  润新知