C++课程设计报告书

课程设计报告书
之前写的,忘发布了...


在C++学习了一段时间之后,我们开始入了课程设计。我选择的题目是:《新生基本信息统计软件》。
题目要求:
有新生来报到,要逐个录入其信息,如:学生姓名,性别,专业,出生日期,家庭地址,英语入学成绩。要求设计链表类来实现,并统计学生人数。文本界面为:

  1. 新增学生信息
  2. 删除学生信息
  3. 导入学生信息(已经保存于的文件信息)
  4. 学生信息搜索(按姓名)
  5. 学生信息统计(按专业或性别或年龄---年龄要自动计算)
  6. 按英语成绩排序
  7. 学生信息保存
  8. 退出
    初学了一些简单的语法之后,感觉要完成一项工程还是有些困难的。
       
        我觉得课程设计的核心,是对链表的操作,实现动态链表的增、删、改、查。还要体现面对对象的思想,相比于C语言的结构体,引入了类的概念。 在写课程设计时,比起一下子打出来完,不如分模块,分功能的有步骤的去写。
    类的创建
    创建了两个类,一个是student类,用于储存学生信息,另一个studentmanage类,用于实现各类功能。
    Studentmanage里的函数,实质上就是指向student的类指针,比如说:Student *Studentmanage::creat() 。

这是一个可控长度的链表,靠的就是不断的新申请空间,直到某终止条件出现,比如我的就是当学生姓名为#时,跳出当前循环,停止录入。
在第一个节点需要特殊处理,即对头结点初始化,之后就是申请空间,初始化,挪指针的循环往复了。重点是最后一个结点的后继要赋空(NULL)。


  1. 此功能是建立在已形成的链表上的,所以如果链表为空,就跳出。
    不为空时,申请一片空间,并初始化。这并不是就插在原链表的最后,而是找了头结点的后一个,把新添加的放到了二者中间。

  1. 和增一样,删要求原本就存在链表。
    按照姓名删除,对比要删除的姓名,如果出现。
    有两种情况,一种是头结点:直接让头指针移向下一位,再把原结点free掉。
    另一种情况:其他结点,令p1指针先向后移动一位,若不是要删除的,就每次向后位移。直到出现要删除结点,
    把该指针的上一个next搭到它的下一个,把它隔过去,再free掉。

  2. 改,查
    这两个的原理差不多,就放到一起说 。都是通过遍历,找到需要的结点,只不过一个找到后重新录入,覆盖原本数据;另一个只是显示。
    为了方便和代码的简洁,在这里我写了displaynode()函数,每次在显示和整改时会方便很多。

  3. 存文件,读文件

这可以说是一个难点了,先说写入文件,即 :
当前黑框---->txt文件
这里就用到了ofstream,文件输出流类,open一个txt,要是没有就新建一个,要是原本有就覆盖。
把头赋给p1后,只要p1存值,就把它写入到out所新建的那个文件里,再让p1移动下一个。
读文件的过程就是一个新建链表的过程,先把头置空,这里有和student类里一样的数据,成功打开文件之后,把里面的数据一个个读出来,并赋值给p1。此处和创建链表也一样,不赘述。

  1. 排序

思想:如果说,原本的链表是无序的,而我最终的目的是创造出有序的。而且我有能力去找到这里面最大的或最小的(遍历就可以了),那么我何不再去创建一个新的链表,它是由原本链表摘出来的节点所组成,那必然是有序的。
和其他操作的最开始一样,传入了头和它之后的一串链表,于以往不同的是,这次开始了直接对头指针的操作。
(366和367是为了防止传进来一个空头造成错误。
核心代码就是white里的循环了:
第一层循环
    目的是为了让头不断向后遍历,只不过这次的目的,就是遍历到终点。期间每执行一次,就让我定义的指针重新指向同一块。
第二层循环
    p(也就是头)的遍历,如果后一个大于前一个,就让后一个成为max,同时定位它的前一个节点,以这种方式标记过后,p再继续向后推进,以实现在循环过后,可以过滤出来最大的,找到了又怎样呢,我们来看接下来的操作。
第一个if(379)
    这时还要考虑到那种情况,也就是头结点万一最大该怎么操作,这也并不难想,直接让head指向下一位,同时断开max(也就是头)与原链表的联系。
其它情况就是,既然上一步(371 while)找出来了max,那么就在这里把它摘出来,令刚刚标记的前一项(pre)指向max的后继,在断开max与原表的联系。
第二个if(387)
    细心的你会发现,在每次的赋值里和之前的几步操作里,都没有用到pnew,不仅如此,它还在一开始就被置空了。
我的目的就是让它成为那个新的链表的头。在之前几步,我们分别找到了max,分离出了max,终于要在这一步为max找一个着落了。
    当然,if第一次肯定是会执行的(因为上来就让pnew置空了),我们让最大的那个节点成了新链表的第一个,那么可想而知的是,在之后几次的循环里,每次都会执行else,并且在里面新摘出来的max被一个个的连到了链表的后面。
    到最后,别忘了还有那个大循环的,它每次执行一遍里面的内容。如是,原本的无序链表每次少一个节点(最大的节点),而新有序链表每次会多一个。
    原链表终结之日,也就是新链表生成之时。届时,循环也就彻底结束了,于是我们令头指针指向那个新生链表(394),再让它们共同指向这条有序的链表,传回去就行了。

  1. 主函数的选择功能

在这里包含两块,先是一个菜单界面menu,它的返回值是一个字符型,由最后的cin写入。下面就紧接着是main函数的switch的选择功能,之所以用char而不用int就是为了规避用户乱输造成的错误。

以下,附上源代码:

#include<iostream>
#include<fstream>   //用来读文件 
#include<iomanip>   //排版 
#include<cstring>//操作字符 ,比较和赋值。
#include<stdlib.h> //new,free
using namespace std;
int n=0;


/*
    1.明明head置空,为什么add,display没有出现预期效果? ok 
    (为什么它又莫名其妙的好了??)
    2.free关键字为什么不存在? ok 
    3.全部删除之后无法新建
    4.排序链断  ok 
    5.多读一次  ok  
*/
    char stop[12]={"#"};
    char name[12];
class Student {
    public:     
        char name[12];
        char sex[3];
        char study[12];     
        char addr[12];
        int birth[3];
        int engli;
        Student *next;
};
class Studentmanage {
    
    private:
        Student *head,*p1,*p2,*p3;
    public:
        Studentmanage () {};
        Student *creat();
        Student *add(Student *head);
        Student *delet(Student *head);
        void *search(Student *head);
        Student *modify(Student *head);
        Student *sort(Student*head);
        void display(Student *head);
        void displaynode(Student *head);
        void write_file(Student *head);
        
        Student * read_file();
        ~Studentmanage () {};
};
    Studentmanage s;
Student *Studentmanage::creat() {
    p1=p2=new Student;
    head=NULL;

    cout<<"请输入学生的基本信息:以姓名为#结束。\n";
    while(1) {
        cout<<"姓名:  \t";
        cin>>p1->name;
        if( strcmp(stop,p1->name)==0 ) {
            break;
        }
        cout<<"性别:  \t";
        cin>>p1->sex;
        
        cout<<"专业:  \t";
        cin>>p1->study;
        
        cout<<"家庭住址:  \t";
        cin>>p1->addr;
        
        cout<<"出生年:";
        cin>>p1->birth[0];      
        cout<<"出生月:";
        cin>> p1->birth[1];
        cout<<"出生日:";
        cin>>p1->birth[2];
        
        cout<<"英语:";
        cin>>p1->engli;
        system("cls");
        
        n=n+1;
        if(n==1)
            head=p1;
        else
            p2->next=p1;
        p2=p1;
        p1=new Student;
    }
    p2->next=NULL;
    return head;
}


Student *Studentmanage::add(Student *head) {
    p1=p3=new Student;  
    p1=head;
        if(p1==NULL)
        {cout<<"在添加前,先新建!";
        return 0;
        }   
        else
        {                    
        cout<<"请输入要添加学生的信息!\n";
        cout<<"姓名:  \t";
        cin>>p3->name;
        cout<<"性别:  \t";
        cin>>p3->sex;   
        cout<<"专业:  \t";
        cin>>p3->study;     
        cout<<"家庭住址:  \t";
        cin>>p3->addr;      
        cout<<"出生年:";
        cin>>p3->birth[0];      
        cout<<"出生月:";
        cin>> p3->birth[1];
        cout<<"出生日:";
        cin>>p3->birth[2];      
        cout<<"英语:";
        cin>>p3->engli;
        cout<<"\n"; 
        
p3->next=p1->next;
p1->next=p3;



    cout<<"添加成功!\n";
    } 
    return head;
}

Student *Studentmanage::delet(Student *head) {  
    p2=p1=new Student;
    if(head==NULL)
    {
        cout<<"没有数据,无法删除";
        return 0;
         
    }
    cout<<"请输入要删除学生的名字:\n";
    cin>>name;
    p2=p1=head;
    int j=0;
    if( ( strcmp(name,head->name)==0 ) && (head!=NULL))
    {
        head=head->next;
        free(p1);
        j=1;    
    } 
    else 
    {
        p1=head->next;
        while(p1!=NULL) {
            if(strcmp(name,p1->name)==0) {
                p2->next=p1->next;
                free(p1);
                j=1;            
                break;
            } else {
                p2=p1;
                p1=p2->next;
            }
        }
    }

    if(j==0)
        cout<<"此学生不存在,删除失败!\n";
    
    else
        cout<<"删除成功!\n";
    return head;
}

void *Studentmanage::search(Student *head) {
     
    p1=new Student;

    cout<<"请输入要查找学生的姓名:\n";
    cin>>name;
    p1=head;
    int j=0;
    while(p1!=NULL) {
        if( strcmp(name,p1->name)==0   ) {
        
        s.displaynode(p1);

            break;
        }
        p1=p1->next;
    }
    if(j==0)
        cout<<"没有找到你要查找学生的信息。\n\n\n";
    else
        cout<<"这是你要查找学生的信息。\n\n\n";
}

Student *Studentmanage::modify(Student *head) {

    if(head==NULL)
    {
        cout<<"没有数据,先新建吧";
        return 0; 
        }   
        char name1[12];
        char sex[3];
        char study[12];     
        char addr[12];
        int birth[3];
        int engli;          
    p1=new Student;
    int j=0;
    p1=head;
    cout<<"请输入你要更改学生的学号:\n";
    cin>>name;

    if(strcmp( name, head->name)==0) {
        cout<<"显示要修改学生的信息:\n";
        s.displaynode(p1);
        
        cout<<"请输入要更改学生的信息:\n";     
        cout<<"姓名:  \t";
        cin>>name1;
        cout<<"性别:  \t";
        cin>>sex;   
        cout<<"专业:  \t";
        cin>>study;     
        cout<<"家庭住址:  \t";
        cin>>addr;      
        cout<<"出生年:";
        cin>>birth[0];      
        cout<<"出生月:";
        cin>>birth[1];
        cout<<"出生日:";
        cin>>birth[2];      
        cout<<"英语:";
        cin>>engli;     
                strcpy(head->name,name1);
                strcpy(head->sex,sex);
                strcpy(head->study,study);
                strcpy(head->addr,addr);
                head->birth[0]=birth[0];
            head->birth[1]=birth[1];
            head->birth[2]=birth[2];
            head->engli=engli;      
        j=1;
    } else {
        p1=head->next;
        while(p1!=NULL) {
            if(strcmp(p1->name,name)==0)    
                cout<<"显示要修改学生的信息:\n";
    s.displaynode(p1);                      
                cout<<"请输入要更改学生的信息:\n";             
        cout<<"姓名:  \t";
        cin>>name1;
        cout<<"性别:  \t";
        cin>>sex;   
        cout<<"专业:  \t";
        cin>>study;     
        cout<<"家庭住址:  \t";
        cin>>addr;      
        cout<<"出生年:";
        cin>>birth[0];      
        cout<<"出生月:";
        cin>>birth[1];
        cout<<"出生日:";
        cin>>birth[2];      
        cout<<"英语:";
        cin>>engli;         
                strcpy(p1->name,name1);
                strcpy(p1->sex,sex);
                strcpy(p1->study,study);
                strcpy(p1->addr,addr);
                p1->birth[0]=birth[0];
                p1->birth[1]=birth[1];
                p1->birth[2]=birth[2];
                p1->engli=engli;
                j=1;
            break;          
        }
    }
    if(j==0)
        cout<<"没有找到你要更改的学生,更改失败!\n";
    else
        cout<<"更改成功!\n";
    return head;
}

void Studentmanage::display(Student *head) {
    p1=head;
    if(p1==NULL)
        cout<<"这是一个空表!请先输入学生信息。"<<endl;
    else {
        while(p1!=NULL) {
            s.displaynode(p1);          
            p1=p1->next;        
        }
    }
}
void Studentmanage::displaynode(Student *head) {
    p1=head;
    if(p1==NULL)
        cout<<"这是一个空表!请先输入学生信息。"<<endl;
    else
    {   
            cout<<"姓名:"<<p1->name<<" 性别:"<<p1->sex<<" 专业:"<<p1->study;          
            cout<<" 家庭住址:"<<p1->addr<<endl;
            cout<<p1->birth[0]<<"年";
            cout<<p1->birth[1]<<"月:"<<p1->birth[2]<<"日 出生:";
            cout<<"年龄:"<<2017-p1->birth[0]<<endl;
            cout<<"英语成绩:"<<p1->engli<<"\n\n";       
    }   
}

Student *Studentmanage::read_file() 
{   
    int i=0;
    char name2[12];
    char study[12];
    char sex[3];
    char addr[12];
    int birth[3];
    int engli;
    p1=p2=new Student;
    head=NULL;
    ifstream in;
    in.open("myC++work.txt");
    if(!in) {
        cout<<"打开文件失败!"<<endl;
    }   
    else
    {

    while(in>>name2>>sex>>study>>addr>>birth[0]>>birth[1]>>birth[2]>>engli) 
    {       
        strcpy(p1->name,name2);
        strcpy(p1->sex,sex);
        strcpy(p1->study,study);
        strcpy(p1->addr,addr);
        p1->birth[0]=birth[0];
        p1->birth[1]=birth[1];
        p1->birth[2]=birth[2];
        p1->engli=engli;
        i++;
        if(i==1) {
            head=p2=p1;
        } else {
            p2->next=p1;
        }
        p2=p1;
        p1=new Student;
        p1->next=NULL;  
    }
cout<<"成功读取文件!内容如下:"<<endl;
    }
    
    return head;
}

void Studentmanage::write_file(Student *head) 
{
    ofstream out;
    out.open("myC++work.txt");
    if(!out) 
    {
        cout<<"打开文件失败!"<<endl;
    }
    p1=NULL;
    p1=head;
    while(p1) {
        out<<p1->name<<setw(5)<<p1->sex<<setw(5)<<p1->study<<setw(5)<<p1->addr<<setw(5)<<p1->birth[0]<<setw(5)<<p1->birth[1]<<setw(5)<<p1->birth[2]<<setw(5)<<p1->engli<<endl;
        p1=p1->next;
    }
    out.close();
    cout<<"写入完毕。"; 
}

Student *Studentmanage::sort(Student *head) 
{
    
    Student*p,*pnew=NULL,*pmax,*ppre;
    if(head==NULL) return 0;
    else {
        while(head->next!=NULL) {
            p=pmax=ppre=head;

            while(p->next!=NULL) {
                if(p->next-> birth[0] > pmax->birth[0]) {
                    pmax=p->next;
                    ppre=p;
                }
                p=p->next;
            }

            if(head==pmax) {
                head=head->next;
                pmax->next=NULL;
            } else {
                ppre->next=pmax->next;
                pmax->next=NULL;
            }

            if(pnew==NULL) {
                pnew=pmax;
            } else {
                pmax->next=pnew;
                pnew=pmax;
            }
        }
        head->next=pnew;
        pnew=head;
        return head;
    }
}



char menu() {
    system("cls");
    char ch;
        
    cout<<"\n\n";

    cout<<"         ******************新生信息统计****************\n";
    cout<<"            1.新建学生档案";
    cout<<"        2.增加学生信息\n";
    cout<<"            3.删除信息";
    cout<<"            4.查询信息\n";
    cout<<"            5.修改信息";
    cout<<"            6.展示信息\n";
    cout<<"            7.读档";
    cout<<"                8.保存并退出\n";
    cout<<"         **********************************************\n";
    cin>>ch;
    return ch;
}

int main ()
 {
    Studentmanage s;
    Student *head;
    head=NULL;
    int n=0;
    char c;
    cout<<"\t\t\t欢迎新生报到!\n\n\n";
    cout<<"\t\t  渗透一班    刘华辉\n";
    cout<<"\n\n\n\n\n\n";
    system("pause");
    while(1)
        switch (menu()) {
            case'1':
                head=s.creat();
                system("pause");
                break;
            case'2':
                head=s.add(head);
                system("pause");
                break;
            case'3':
                head=s.delet(head);
                system("pause");
                break;
            case'4':
                s.search(head);
                system("pause");
                break;
            case'5':
                head=s.modify(head);
                system("pause");
                break;
            case'6':
                s.sort(head);
                s.display(head);
                system("pause");
                break;
            case'7':
                head=s.read_file();
                s.display(head); 
                system("pause");
                break;
            case'8':                
                s.write_file(head);
                cout<<"谢谢使用!再见!\n";
                system("pause");
                return 0;                                           
            default:
                cout<<"选择有错,请重新选择\n";
        }
    return 0;

}









©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 206,214评论 6 481
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 88,307评论 2 382
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 152,543评论 0 341
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 55,221评论 1 279
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 64,224评论 5 371
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,007评论 1 284
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,313评论 3 399
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,956评论 0 259
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 43,441评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,925评论 2 323
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,018评论 1 333
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,685评论 4 322
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,234评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,240评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,464评论 1 261
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,467评论 2 352
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,762评论 2 345

推荐阅读更多精彩内容

  • B树的定义 一棵m阶的B树满足下列条件: 树中每个结点至多有m个孩子。 除根结点和叶子结点外,其它每个结点至少有m...
    文档随手记阅读 13,181评论 0 25
  • 1.把二元查找树转变成排序的双向链表 题目: 输入一棵二元查找树,将该二元查找树转换成一个排序的双向链表。 要求不...
    曲终人散Li阅读 3,294评论 0 19
  • 作为刚刚学习C的新手,水平较低,难免出错。希望各位前辈不吝赐教,批评指正。 1.显示主菜单 在复杂面前,先做一些微...
    _return_阅读 1,799评论 4 10
  • 帕多瓦(Padova),一座像露天博物馆一样精美的意大利小城,路过即爱上。 到帕多瓦的第一印象就是灼人的酷暑,湛蓝...
    贵州宝拉教育阅读 400评论 0 1
  • 闵杏郁,温州圣卡萝服饰有限公司;63期同修、79期志工、116期志工、160期志工、203期志工 【日精进打卡第3...
    杏郁阅读 157评论 0 0