C++課程設(shè)計(jì)報(bào)告書(shū)

課程設(shè)計(jì)報(bào)告書(shū)
之前寫(xiě)的,忘發(fā)布了...


在C++學(xué)習(xí)了一段時(shí)間之后,我們開(kāi)始入了課程設(shè)計(jì)。我選擇的題目是:《新生基本信息統(tǒng)計(jì)軟件》。
題目要求:
有新生來(lái)報(bào)到,要逐個(gè)錄入其信息,如:學(xué)生姓名,性別,專(zhuān)業(yè),出生日期,家庭地址,英語(yǔ)入學(xué)成績(jī)。要求設(shè)計(jì)鏈表類(lèi)來(lái)實(shí)現(xiàn),并統(tǒng)計(jì)學(xué)生人數(shù)。文本界面為:

  1. 新增學(xué)生信息
  2. 刪除學(xué)生信息
  3. 導(dǎo)入學(xué)生信息(已經(jīng)保存于的文件信息)
  4. 學(xué)生信息搜索(按姓名)
  5. 學(xué)生信息統(tǒng)計(jì)(按專(zhuān)業(yè)或性別或年齡---年齡要自動(dòng)計(jì)算)
  6. 按英語(yǔ)成績(jī)排序
  7. 學(xué)生信息保存
  8. 退出
    初學(xué)了一些簡(jiǎn)單的語(yǔ)法之后,感覺(jué)要完成一項(xiàng)工程還是有些困難的。
    ???
    ????我覺(jué)得課程設(shè)計(jì)的核心,是對(duì)鏈表的操作,實(shí)現(xiàn)動(dòng)態(tài)鏈表的增、刪、改、查。還要體現(xiàn)面對(duì)對(duì)象的思想,相比于C語(yǔ)言的結(jié)構(gòu)體,引入了類(lèi)的概念。?在寫(xiě)課程設(shè)計(jì)時(shí),比起一下子打出來(lái)完,不如分模塊,分功能的有步驟的去寫(xiě)。
    類(lèi)的創(chuàng)建
    創(chuàng)建了兩個(gè)類(lèi),一個(gè)是student類(lèi),用于儲(chǔ)存學(xué)生信息,另一個(gè)studentmanage類(lèi),用于實(shí)現(xiàn)各類(lèi)功能。
    Studentmanage里的函數(shù),實(shí)質(zhì)上就是指向student的類(lèi)指針,比如說(shuō):Student *Studentmanage::creat() 。

這是一個(gè)可控長(zhǎng)度的鏈表,靠的就是不斷的新申請(qǐng)空間,直到某終止條件出現(xiàn),比如我的就是當(dāng)學(xué)生姓名為#時(shí),跳出當(dāng)前循環(huán),停止錄入。
在第一個(gè)節(jié)點(diǎn)需要特殊處理,即對(duì)頭結(jié)點(diǎn)初始化,之后就是申請(qǐng)空間,初始化,挪指針的循環(huán)往復(fù)了。重點(diǎn)是最后一個(gè)結(jié)點(diǎn)的后繼要賦空(NULL)。


  1. 此功能是建立在已形成的鏈表上的,所以如果鏈表為空,就跳出。
    不為空時(shí),申請(qǐng)一片空間,并初始化。這并不是就插在原鏈表的最后,而是找了頭結(jié)點(diǎn)的后一個(gè),把新添加的放到了二者中間。

  1. 和增一樣,刪要求原本就存在鏈表。
    按照姓名刪除,對(duì)比要?jiǎng)h除的姓名,如果出現(xiàn)。
    有兩種情況,一種是頭結(jié)點(diǎn):直接讓頭指針移向下一位,再把原結(jié)點(diǎn)free掉。
    另一種情況:其他結(jié)點(diǎn),令p1指針先向后移動(dòng)一位,若不是要?jiǎng)h除的,就每次向后位移。直到出現(xiàn)要?jiǎng)h除結(jié)點(diǎn),
    把該指針的上一個(gè)next搭到它的下一個(gè),把它隔過(guò)去,再free掉。

  2. 改,查
    這兩個(gè)的原理差不多,就放到一起說(shuō) 。都是通過(guò)遍歷,找到需要的結(jié)點(diǎn),只不過(guò)一個(gè)找到后重新錄入,覆蓋原本數(shù)據(jù);另一個(gè)只是顯示。
    為了方便和代碼的簡(jiǎn)潔,在這里我寫(xiě)了displaynode()函數(shù),每次在顯示和整改時(shí)會(huì)方便很多。

  3. 存文件,讀文件

這可以說(shuō)是一個(gè)難點(diǎn)了,先說(shuō)寫(xiě)入文件,即 :
當(dāng)前黑框---->txt文件
這里就用到了ofstream,文件輸出流類(lèi),open一個(gè)txt,要是沒(méi)有就新建一個(gè),要是原本有就覆蓋。
把頭賦給p1后,只要p1存值,就把它寫(xiě)入到out所新建的那個(gè)文件里,再讓p1移動(dòng)下一個(gè)。
讀文件的過(guò)程就是一個(gè)新建鏈表的過(guò)程,先把頭置空,這里有和student類(lèi)里一樣的數(shù)據(jù),成功打開(kāi)文件之后,把里面的數(shù)據(jù)一個(gè)個(gè)讀出來(lái),并賦值給p1。此處和創(chuàng)建鏈表也一樣,不贅述。

  1. 排序

思想:如果說(shuō),原本的鏈表是無(wú)序的,而我最終的目的是創(chuàng)造出有序的。而且我有能力去找到這里面最大的或最小的(遍歷就可以了),那么我何不再去創(chuàng)建一個(gè)新的鏈表,它是由原本鏈表摘出來(lái)的節(jié)點(diǎn)所組成,那必然是有序的。
和其他操作的最開(kāi)始一樣,傳入了頭和它之后的一串鏈表,于以往不同的是,這次開(kāi)始了直接對(duì)頭指針的操作。
(366和367是為了防止傳進(jìn)來(lái)一個(gè)空頭造成錯(cuò)誤。
核心代碼就是white里的循環(huán)了:
第一層循環(huán)
????目的是為了讓頭不斷向后遍歷,只不過(guò)這次的目的,就是遍歷到終點(diǎn)。期間每執(zhí)行一次,就讓我定義的指針重新指向同一塊。
第二層循環(huán)
????p(也就是頭)的遍歷,如果后一個(gè)大于前一個(gè),就讓后一個(gè)成為max,同時(shí)定位它的前一個(gè)節(jié)點(diǎn),以這種方式標(biāo)記過(guò)后,p再繼續(xù)向后推進(jìn),以實(shí)現(xiàn)在循環(huán)過(guò)后,可以過(guò)濾出來(lái)最大的,找到了又怎樣呢,我們來(lái)看接下來(lái)的操作。
第一個(gè)if(379)
????這時(shí)還要考慮到那種情況,也就是頭結(jié)點(diǎn)萬(wàn)一最大該怎么操作,這也并不難想,直接讓head指向下一位,同時(shí)斷開(kāi)max(也就是頭)與原鏈表的聯(lián)系。
其它情況就是,既然上一步(371 while)找出來(lái)了max,那么就在這里把它摘出來(lái),令剛剛標(biāo)記的前一項(xiàng)(pre)指向max的后繼,在斷開(kāi)max與原表的聯(lián)系。
第二個(gè)if(387)
????細(xì)心的你會(huì)發(fā)現(xiàn),在每次的賦值里和之前的幾步操作里,都沒(méi)有用到pnew,不僅如此,它還在一開(kāi)始就被置空了。
我的目的就是讓它成為那個(gè)新的鏈表的頭。在之前幾步,我們分別找到了max,分離出了max,終于要在這一步為max找一個(gè)著落了。
????當(dāng)然,if第一次肯定是會(huì)執(zhí)行的(因?yàn)樯蟻?lái)就讓pnew置空了),我們讓最大的那個(gè)節(jié)點(diǎn)成了新鏈表的第一個(gè),那么可想而知的是,在之后幾次的循環(huán)里,每次都會(huì)執(zhí)行else,并且在里面新摘出來(lái)的max被一個(gè)個(gè)的連到了鏈表的后面。
????到最后,別忘了還有那個(gè)大循環(huán)的,它每次執(zhí)行一遍里面的內(nèi)容。如是,原本的無(wú)序鏈表每次少一個(gè)節(jié)點(diǎn)(最大的節(jié)點(diǎn)),而新有序鏈表每次會(huì)多一個(gè)。
????原鏈表終結(jié)之日,也就是新鏈表生成之時(shí)。屆時(shí),循環(huán)也就徹底結(jié)束了,于是我們令頭指針指向那個(gè)新生鏈表(394),再讓它們共同指向這條有序的鏈表,傳回去就行了。

  1. 主函數(shù)的選擇功能

在這里包含兩塊,先是一個(gè)菜單界面menu,它的返回值是一個(gè)字符型,由最后的cin寫(xiě)入。下面就緊接著是main函數(shù)的switch的選擇功能,之所以用char而不用int就是為了規(guī)避用戶(hù)亂輸造成的錯(cuò)誤。

以下,附上源代碼:

#include<iostream>
#include<fstream>   //用來(lái)讀文件 
#include<iomanip>   //排版 
#include<cstring>//操作字符 ,比較和賦值。
#include<stdlib.h> //new,free
using namespace std;
int n=0;


/*
    1.明明head置空,為什么add,display沒(méi)有出現(xiàn)預(yù)期效果? ok 
    (為什么它又莫名其妙的好了??)
    2.free關(guān)鍵字為什么不存在? ok 
    3.全部刪除之后無(wú)法新建
    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<<"請(qǐng)輸入學(xué)生的基本信息:以姓名為#結(jié)束。\n";
    while(1) {
        cout<<"姓名:  \t";
        cin>>p1->name;
        if( strcmp(stop,p1->name)==0 ) {
            break;
        }
        cout<<"性別:  \t";
        cin>>p1->sex;
        
        cout<<"專(zhuān)業(yè):  \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<<"英語(yǔ):";
        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<<"請(qǐng)輸入要添加學(xué)生的信息!\n";
        cout<<"姓名:  \t";
        cin>>p3->name;
        cout<<"性別:  \t";
        cin>>p3->sex;   
        cout<<"專(zhuān)業(yè):  \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<<"英語(yǔ):";
        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<<"沒(méi)有數(shù)據(jù),無(wú)法刪除";
        return 0;
         
    }
    cout<<"請(qǐng)輸入要?jiǎng)h除學(xué)生的名字:\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<<"此學(xué)生不存在,刪除失敗!\n";
    
    else
        cout<<"刪除成功!\n";
    return head;
}

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

    cout<<"請(qǐng)輸入要查找學(xué)生的姓名:\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<<"沒(méi)有找到你要查找學(xué)生的信息。\n\n\n";
    else
        cout<<"這是你要查找學(xué)生的信息。\n\n\n";
}

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

    if(head==NULL)
    {
        cout<<"沒(méi)有數(shù)據(jù),先新建吧";
        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<<"請(qǐng)輸入你要更改學(xué)生的學(xué)號(hào):\n";
    cin>>name;

    if(strcmp( name, head->name)==0) {
        cout<<"顯示要修改學(xué)生的信息:\n";
        s.displaynode(p1);
        
        cout<<"請(qǐng)輸入要更改學(xué)生的信息:\n";     
        cout<<"姓名:  \t";
        cin>>name1;
        cout<<"性別:  \t";
        cin>>sex;   
        cout<<"專(zhuān)業(yè):  \t";
        cin>>study;     
        cout<<"家庭住址:  \t";
        cin>>addr;      
        cout<<"出生年:";
        cin>>birth[0];      
        cout<<"出生月:";
        cin>>birth[1];
        cout<<"出生日:";
        cin>>birth[2];      
        cout<<"英語(yǔ):";
        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<<"顯示要修改學(xué)生的信息:\n";
    s.displaynode(p1);                      
                cout<<"請(qǐng)輸入要更改學(xué)生的信息:\n";             
        cout<<"姓名:  \t";
        cin>>name1;
        cout<<"性別:  \t";
        cin>>sex;   
        cout<<"專(zhuān)業(yè):  \t";
        cin>>study;     
        cout<<"家庭住址:  \t";
        cin>>addr;      
        cout<<"出生年:";
        cin>>birth[0];      
        cout<<"出生月:";
        cin>>birth[1];
        cout<<"出生日:";
        cin>>birth[2];      
        cout<<"英語(yǔ):";
        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<<"沒(méi)有找到你要更改的學(xué)生,更改失??!\n";
    else
        cout<<"更改成功!\n";
    return head;
}

void Studentmanage::display(Student *head) {
    p1=head;
    if(p1==NULL)
        cout<<"這是一個(gè)空表!請(qǐng)先輸入學(xué)生信息。"<<endl;
    else {
        while(p1!=NULL) {
            s.displaynode(p1);          
            p1=p1->next;        
        }
    }
}
void Studentmanage::displaynode(Student *head) {
    p1=head;
    if(p1==NULL)
        cout<<"這是一個(gè)空表!請(qǐng)先輸入學(xué)生信息。"<<endl;
    else
    {   
            cout<<"姓名:"<<p1->name<<" 性別:"<<p1->sex<<" 專(zhuān)業(yè):"<<p1->study;          
            cout<<" 家庭住址:"<<p1->addr<<endl;
            cout<<p1->birth[0]<<"年";
            cout<<p1->birth[1]<<"月:"<<p1->birth[2]<<"日 出生:";
            cout<<"年齡:"<<2017-p1->birth[0]<<endl;
            cout<<"英語(yǔ)成績(jī):"<<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<<"打開(kāi)文件失?。?<<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<<"成功讀取文件!內(nèi)容如下:"<<endl;
    }
    
    return head;
}

void Studentmanage::write_file(Student *head) 
{
    ofstream out;
    out.open("myC++work.txt");
    if(!out) 
    {
        cout<<"打開(kāi)文件失?。?<<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<<"寫(xiě)入完畢。"; 
}

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<<"         ******************新生信息統(tǒng)計(jì)****************\n";
    cout<<"            1.新建學(xué)生檔案";
    cout<<"        2.增加學(xué)生信息\n";
    cout<<"            3.刪除信息";
    cout<<"            4.查詢(xún)信息\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歡迎新生報(bào)到!\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<<"謝謝使用!再見(jiàn)!\n";
                system("pause");
                return 0;                                           
            default:
                cout<<"選擇有錯(cuò),請(qǐng)重新選擇\n";
        }
    return 0;

}









?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀(guān)點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容