可以增刪查改,使用鏈表存儲,支持排序以及文件存儲及數據讀取,基本可以應付期末大作業(狗頭) 界面為

源代碼為一個main.cpp和三個頭文件,具體為 main.cpp
#include <iostream>
#include <fstream>//文件操作
#include <sstream>//int轉string
#include <iomanip>//cout格式化輸出 setw()
#include <stdlib.h>
#include "student.h"
#include "node.h"
#include "list.h"
using namespace std;int main()//入口函數
{//test();CList list1;//創建鏈表對象Read4File(list1);//將文件數據讀取到鏈表中int choice = -1;//接收用戶選擇while(true){system("cls");//清屏MainMenu();cin>>choice;switch(choice){case 1:system("cls");//清屏cout<<"********【所有數據】********"<<endl;cout<<"序號t學號 姓名 班級 分數"<<endl;cout<<"*******【共 "<<list1.DisplayListData()<<" 人】******n"<<endl;list1.Compute(); system("pause");//暫停一下break;case 2:Add(list1);//添加操作break;case 3:Find(list1);//查找操作break;case 4:Update(list1);//更新操作(修改)break;case 5:Sort(list1);//排序操作break;case 6:Del(list1);//刪除操作break;case 7:ClearFileData();//清空文件數據list1.Clear();//清空鏈表數據break;case 0://退出程序return 0;default:cout<<"請輸入0~7"<<endl;system("pause");break;}}return 0;
}
list.h
#include <iostream>
#include <fstream>
#include <sstream>
#include <iomanip>
#include <stdlib.h>
#define FILE_PATH "student.txt" //數據文件的路徑
using namespace std;
//聲明
class CList;
void Save2File(CList& list);//將數據保存到文件
void Read4File(CList& list);//讀取文件數據到鏈表bool CmpStr(string str1, string str2)//字符串比較函數
{int len1 = str1.size();//字符串1的長度int len2 = str2.size();//字符串2的長度//將兩個字符串的長度 添加為一樣長(達到右對齊的效果)for(int i=0; i<len1-len2; i++)//如果字符串str1比str2長,在str2的前面補0{str2.insert(0, "0");//在最前面補0}for(int i=0; i<len2-len1; i++)//如果字符串str2比str1長,在str1的前面補0{str1.insert(0, "0");//在最前面補0}return str1>str2;
}bool SortById(SNode* &p, SNode* &q)//按學號升序排序
{return ( p->stu.GetId()>q->stu.GetId() );
}bool SortByName(SNode* &p, SNode* &q)//按姓名升序排序
{return CmpStr(p->stu.GetName(), q->stu.GetName());
}bool SortByClass(SNode* &p, SNode* &q)//按班級升序排序
{return CmpStr(p->stu.GetClass(), q->stu.GetClass());
}
bool SortByScore(SNode* &p, SNode* &q)//按Score升序排序
{return ( p->stu.GetScore()>q->stu.GetScore() );
}typedef bool (*FUNCP)(SNode* &p, SNode* &q);//函數指針
FUNCP pFunArr[] = {SortById, SortByName, SortByClass,SortByScore};//排序函數的指針數組//鏈表操作類
class CList
{SNode* m_pListHead;//鏈表頭結點指針void Init_ListHead();//初始化頭結點
public:CList();//無參構造函數,用來初始化成員,創建對象的時候自動調用~CList();//析構函數,用來釋放格外申請的堆空間,(對象被銷毀的時候自動調用)void AddHead(SNode& node);//頭插法 添加數據void AddTail(SNode& node);//尾插法 添加數據bool DelData(int id);//根據id刪除數據SNode* FindData(int id);//根據id查找指定數據bool UpdateData(int id, SNode& update);//根據id修改數據(更新)int DisplayListData();//顯示鏈表所有數據,返回數據條數SNode* GetListHead();//外界獲取頭結點指針的接口(頭指針是private權限)void Clear();//清空鏈表。釋放鏈表空間void Sort(int type = 0);//默認按id升序排序int Size();void Compute();//獲取鏈表數據的個數
};//類成員函數的類外實現
CList::CList()//無參構造函數,用來初始化成員
{Init_ListHead();//初始化鏈表頭結點
}CList::~CList()//析構函數,用來釋放格外申請的堆空間,(對象被銷毀的時候自動調用)
{Clear();//釋放鏈表空間delete m_pListHead;//釋放頭結點,m_pListHead = NULL;//置空,防止重復操作
}
void CList::Compute()//根據id升序排序
{ int a=0,b=0,c=0;if(m_pListHead == NULL)//空鏈表直接返回{return;}SNode* p; //排序輔助指針(以p為基準,q遍歷連鏈表數據,temp在交換的數據時使用,指向需要交換時的較大者)for(p = m_pListHead->next;p != NULL;p = p->next){if(p->stu.GetScore()<60)a++;else if(p->stu.GetScore()>=60&&p->stu.GetScore()<=80)b++;else if(p->stu.GetScore()>80)c++;}cout<<"60分以下(不含60分)的人數有:"<<a<<"人"<<endl;cout<<"60分以上80分以下(含80分)的人數有:"<<b<<"人"<<endl;cout<<"80分以上的人數有:"<<c<<"人"<<endl;if((a+b+c)!=0)cout<<"及格率為:"<<(float)(b+c)/(a+b+c)*100<<"%"<<endl;}void CList::Init_ListHead()//初始化頭結點
{m_pListHead = new SNode;//初始化頭結點m_pListHead->stu.SetId(0);m_pListHead->stu.SetName("頭結點");m_pListHead->stu.SetClass("A班");m_pListHead->stu.SetScore(0);m_pListHead->next = NULL;
}void CList::AddHead(SNode& node)//頭插法 添加數據
{SNode* new_node = new SNode(node);new_node->next = NULL;if(m_pListHead == NULL)//頭結點為空,就初始化頭結點{Init_ListHead();}if(m_pListHead->next == NULL)//如果除頭結點外還沒有數據節點,直接讓頭結點指向新的節點,新的節點作為第一個數據節點{m_pListHead->next = new_node;}else //將新的節點作為第一個數據節點(頭結點后面的一個){new_node->next = m_pListHead->next;m_pListHead->next = new_node;}
}void CList::AddTail(SNode& node)//尾插法 添加數據
{SNode* new_node = new SNode(node);new_node->next = NULL;if(m_pListHead == NULL)//頭結點為空,就初始化頭結點{Init_ListHead();}SNode* p = m_pListHead;while(p->next)//遍歷到鏈表最后一個節點,直到p->next為NULL{p = p->next;}p->next = new_node;//鏈表最后的節點指向新的節點,新的節點成為尾節點}bool CList::DelData(int id)//根據id刪除數據
{if(m_pListHead == NULL){return false;}SNode* p = m_pListHead->next;//p遍歷節點SNode* q = m_pListHead;//q為p的前一個節點while(p != NULL)//遍歷鏈表{if(id == p->stu.GetId())//找到要刪除的數據節點p{q->next = p->next;delete p;p = NULL;//置空,防止再次操作造成隱蔽錯誤return true;}q = p;p = p->next;}return false;
}SNode* CList::FindData(int id)//根據id查找指定數據
{if(m_pListHead == NULL){return NULL;}SNode* p = m_pListHead->next;//p遍歷節點while(p != NULL)//遍歷鏈表{if(id == p->stu.GetId())//找到要刪除的數據節點p{return p;}p = p->next;}return NULL;
}bool CList::UpdateData(int id, SNode& update)//根據id修改數據(更新)
{if(m_pListHead == NULL){return false;}SNode* findNode = NULL;findNode = FindData(id);if(findNode != NULL){//memcpy(findNode, &update, sizeof(SNode)-sizeof(SNode*));//更新數據,不更新指針域findNode->stu.SetId(update.stu.GetId());findNode->stu.SetName(update.stu.GetName());findNode->stu.SetClass(update.stu.GetClass());findNode->stu.SetScore(update.stu.GetScore());return true;}return false;
}int CList::DisplayListData()//顯示鏈表所有數據
{if(m_pListHead == NULL){return 0;}int count = 0;//記錄數據的總條數SNode* p = m_pListHead->next;while(p != NULL)//遍歷鏈表{count++;cout<<"["<<count<<"]t"<<setw(4)<<p->stu.GetId()<<" "<<setw(8)<<p->stu.GetName()<<" "<<setw(8)<<p->stu.GetClass()<<setw(8)<<p->stu.GetScore()<<endl;//(setw(8)輸出寬度,默認右對齊)p = p->next;}return count;
}void CList::Clear()//清空鏈表。釋放鏈表空間
{if(m_pListHead == NULL){return;}SNode* p = m_pListHead->next;while(p != NULL)//遍歷鏈表{m_pListHead->next = p->next;delete p;p = m_pListHead->next;}
}void CList::Sort(int type)//排序
{if(m_pListHead == NULL)//空鏈表直接返回{return;}SNode* p, *q, *bigger;//排序輔助指針(以p為基準,q遍歷連鏈表數據,temp在交換的數據時使用,指向需要交換時的較大者)for(p = m_pListHead->next;p != NULL;p = p->next){bigger = p;for(q = p->next;q != NULL;q = q->next){if( pFunArr[type](bigger, q) )//前面的比后面的大,就交換{bigger = q;//指向需要交換時的較大者}}if(bigger != p)//需要交換{SNode temp = *bigger;//指針域不用交換bigger->stu.SetId(p->stu.GetId());bigger->stu.SetName(p->stu.GetName());bigger->stu.SetClass(p->stu.GetClass());bigger->stu.SetScore(p->stu.GetScore());p->stu.SetId(temp.stu.GetId());p->stu.SetName(temp.stu.GetName());p->stu.SetClass(temp.stu.GetClass());p->stu.SetScore(temp.stu.GetScore());}}
}SNode* CList::GetListHead()//外界獲取頭結點指針的接口(頭指針是private權限)
{return this->m_pListHead;
}int CList::Size()
{if(m_pListHead == NULL){return 0;}int count = 0;//數據的個數SNode* p = m_pListHead;while( (p=p->next) != NULL){count++;}return count;
}void AddMenu()//添加 菜單
{cout<<"┏━━━━━━━━━━┓"<<endl;cout<<"┃ 添加菜單 ┃"<<endl;cout<<"┃ 【1】 添加到頭部 ┃"<<endl;cout<<"┃ 【2】 添加到尾部 ┃"<<endl;cout<<"┃ 【0】 返回 ┃"<<endl;cout<<"┗━━━━━━━━━━┛"<<endl;cout<<" ******請輸入0~2:";
}void Add(CList& list)//添加處理
{int id = -1;//接收用戶輸入的idstring name = "";//接收用戶輸入的姓名string _class = "";//接收用戶輸入的班級float score =0;SNode new_node;//存儲輸入的合法數據int choice = -1;//接收用戶選擇char save = 'Y';//是否將數據保存到文件char isAdd = 'N';//用來表識 用戶是否有添加過數據,如果有會在返回上級菜單的時候提示用戶保存到文件char isContinue = 'Y';//表識是否繼續添加while(true){system("cls");//清屏AddMenu();//添加菜單cin>>choice;//接收用戶選擇switch(choice){case 1://頭插法case 2://尾部添加isContinue = 'Y';while(isContinue == 'Y' || isContinue == 'y')//循環添加{cout<<"請輸入學號:";cin>>id;if(id<=0)//檢查用戶輸入的id是否合法{cout<<"序號應大于0!請重新輸入!"<<endl;}else if(list.FindData(id) != NULL)//學號大于0但是已經存在{cout<<"學號 "<<id<<" 已經存在!請重新輸入!"<<endl;}else//學號大于0且不存在{new_node.stu.SetId(id);//設置新的學號for(;;)//循環接收用戶輸入的姓名,直到姓名不為空{cout<<"請輸入姓名:";cin>>name;if(name.empty())//如果姓名為空{cout<<"姓名 不能為空!請重新輸入!(按0結束輸入)"<<endl;continue;}break;}if(name == "0")//如果姓名為0,結束添加{break;//跳出循環}new_node.stu.SetName(name);//設新節點的姓名for(;;)//循環接收用戶輸入的班級,直到班級不為空{cout<<"請輸入班級:";cin>>_class;if(_class.empty())//如果班級為空{cout<<"班級 不能為空!請重新輸入!(按0結束輸入)"<<endl;continue;}break;}if(_class == "0")//如果班級為0,結束添加{break;//跳出循環}new_node.stu.SetClass(_class);//設置新節點的班級for(;;)//循環接收用戶輸入的score,直到score不為空{cout<<"請輸入分數:";cin>>score;if(score<0){cout<<"分數不能為負!請重新輸入!(按0結束輸入)"<<endl;continue;}break;}if(score==0)//如果分數為0,結束添加{break;//跳出循環}new_node.stu.SetScore(score);if(choice == 1){list.AddHead(new_node);//頭插法添加到鏈表}else{list.AddTail(new_node);//尾插法添加到鏈表}isAdd = 'Y';//表識用戶添加了數據}cout<<"是否繼續添加?(y/n):";cin>>isContinue;}break;case 0:if(isAdd == 'Y')//用戶添加過數據才提示保存{cout<<"是否保存到文件?(y/n)"<<endl;cin>>save;if(save == 'Y'|| save == 'y'){Save2File(list);//將數據保存到文件cout<<"保存成功!"<<endl;system("pause");}else//不保存{list.Clear();//清除數據Read4File(list);//重新讀取數據}}return;default:cout<<"請輸入0~2"<<endl;system("pause");break;}}
}void DelMenu()//刪除菜單
{cout<<"┏━━━━━━━━━━┓"<<endl;cout<<"┃ 刪除菜單 ┃"<<endl;cout<<"┃ 【1】 按學號刪除 ┃"<<endl;cout<<"┃ 【0】 返回 ┃"<<endl;cout<<"┗━━━━━━━━━━┛"<<endl;cout<<" ******請輸入0~1:";
}void Del(CList& list)//刪除操作
{int id = -1;char choice = '0';//用戶選擇bool isDel = false;//接收刪除結果char isSure = 'N';//提示用戶 確認刪除SNode* findNode = NULL;//指向匹配的數據節點while(true){system("cls");//清屏DelMenu();cin>>choice;if(choice == '1'){cout<<"請輸入要刪除的學號:";}else{break;}cin>>id;if(id == 0){break;}findNode = list.FindData(id);if(findNode != NULL)//存在目標數據{cout<<"學號"<<"t"<<"姓名"<<"t"<<"班級"<<"t"<<"分數"<<endl;cout<<findNode->stu.GetId()<<"t"<<findNode->stu.GetName()<<"t"<<findNode->stu.GetClass()<<endl;cout<<"已經找到學號為 "<<id<<"的數據,是否刪除?(y/n):";cin>>isSure;if(isSure == 'Y' || isSure == 'y')//用戶確認刪除{isDel = list.DelData(id);Save2File(list);//保存到文件if(isDel)//刪除成功{cout<<"已成功刪除id為"<<id<<"的數據"<<endl;}else{cout<<"刪除id為"<<id<<"的數據 失敗!"<<endl;}}}else{cout<<"請檢查"<<id<<"是否存在!"<<endl;}system("pause");}
}void FindMenu()//查找的菜單
{cout<<"┏━━━━━━━━━━┓"<<endl;cout<<"┃ 查找菜單 ┃"<<endl;cout<<"┃ 【1】 按學號查找 ┃"<<endl;cout<<"┃ 【2】 按姓名查找 ┃"<<endl;cout<<"┃ 【3】 按班級查找 ┃"<<endl;cout<<"┃ 【0】 返回 ┃"<<endl;cout<<"┗━━━━━━━━━━┛"<<endl;cout<<" ******請輸入0~3:";
}void Find(CList& list)//查找操作
{int id = -1;//存放要查找的學號string name_class = "";//存放要查找的姓名(或班級)int choice = -1;//接收用戶的選擇SNode* findNode = NULL;//接收查找結果while(true){system("cls");//清屏FindMenu();//查找菜單cin>>choice;//接收用戶選擇switch(choice){case 1://按學號查找,因為學號是唯一的,所以最多只有一個匹配的數據cout<<"請輸入要查找的學號:";cin>>id;findNode = list.FindData(id);if(findNode != NULL)//找到數據{cout<<"n已經找到id為"<<id<<"的數據"<<endl;cout<<"學號"<<"t"<<"姓名"<<"t"<<"班級"<<endl;cout<<findNode->stu.GetId()<<"t"<<findNode->stu.GetName()<<"t"<<findNode->stu.GetClass()<<"t"<<findNode->stu.GetScore()<<endl;}else{cout<<"未找到,請檢查學號 "<<id<<" 是否存在!"<<endl;}break;case 2://按姓名查找,可能有重名的,所以結果可能包含多個數據case 3:{if(choice == 2){cout<<"請輸入要查找的姓名:";}else{cout<<"請輸入要查找的班級:";}cin>>name_class;CList findList;//存放查詢的結果findNode = list.GetListHead();//獲取鏈表頭結點if(findNode != NULL){findNode = findNode->next;while(findNode != NULL)//遍歷數據鏈表,匹配就添加到結果鏈表{if( ((choice == 2) && name_class == findNode->stu.GetName()) ||((choice == 3) && name_class == findNode->stu.GetClass()))//姓名(或班級)匹配{findList.AddTail(*findNode);//添加到結果鏈表中}findNode = findNode->next;}}int count = findList.Size();//匹配到的數據數目if( count>0 )//如果結果鏈表中匹配到有數據{if(choice == 2){cout<<"n已經找到姓名為 "<<name_class<<" 的數據"<<endl;}else{cout<<"n已經找到班級為 "<<name_class<<" 的數據"<<endl;}cout<<"學號"<<"t"<<"姓名"<<"t"<<"班級"<<endl;findNode = findList.GetListHead()->next;while(findNode != NULL){cout<<findNode->stu.GetId()<<"t"<<findNode->stu.GetName()<<"t"<<findNode->stu.GetClass()<<endl;findNode = findNode->next;}cout<<"*****【共 "<<count<<" 名學生】*****n"<<endl;}else{if(choice == 2){cout<<"未找到,請檢查姓名 "<<name_class<<" 是否存在!"<<endl;}else{cout<<"未找到,請檢查班級 "<<name_class<<" 是否存在!"<<endl;}}break;}case 0://返回return;default:cout<<"請輸入0~3"<<endl;break;}system("pause");}
}void UpdateMenu()//更新菜單
{cout<<"┏━━━━━━━━━━┓"<<endl;cout<<"┃ 更新菜單 ┃"<<endl;cout<<"┃ 【1】 按學號更新 ┃"<<endl;cout<<"┃ 【0】 返回 ┃"<<endl;cout<<"┗━━━━━━━━━━┛"<<endl;cout<<" ******請輸入0~1:";
}void Update(CList& list)//更新操作
{int id = -1;int choice = -1;//用戶的選擇bool isUpdate = NULL;//接收修改結果string name = "";//新的姓名string _class = "";//新的班級float score=0;SNode* findNode = NULL;//指向要更新的節點SNode update;//新的數據while(true){system("cls");//清屏UpdateMenu();//更新菜單cin>>choice;//接收用戶選擇switch(choice){case 1:cout<<"請輸入要更新的學號:";cin>>id;findNode = list.FindData(id);if(findNode == NULL)//不存在目標數據,則重新輸入{cout<<"不存在此學號!"<<endl;system("pause");continue;}cout<<"n已經找到id為"<<id<<"的數據"<<endl;cout<<"學號"<<"t"<<"姓名"<<"t"<<"班級"<<"t"<<"分數"<<endl;cout<<findNode->stu.GetId()<<"t"<<findNode->stu.GetName()<<"t"<<findNode->stu.GetClass()<<"t"<<findNode->stu.GetScore()<<endl;update = *findNode;cout<<"【輸入0,表示不更改】"<<endl;cout<<"將姓名:"<<findNode->stu.GetName()<<" 改為:";cin>>name;if(name != "0"){update.stu.SetName(name);}cout<<"將分數:"<<findNode->stu.GetScore()<<" 改為:";cin>>score;if(score != 0){update.stu.SetScore(score);}cout<<"將班級:"<<findNode->stu.GetClass()<<" 改為:";cin>>_class;if(_class != "0"){update.stu.SetClass(_class);}if(name != "0" || _class != "0")//用戶有更改{isUpdate = list.UpdateData(id, update);if(isUpdate == true){Save2File(list);//保存到文件cout<<"更新成功!"<<endl;}else{cout<<"更新失敗!"<<endl;}}else{cout<<"未更改!"<<endl;}break;case 0:return;default:cout<<"請輸入0~1"<<endl;break;}system("pause");//因為有清屏動作,所以暫停一下,讓用戶查看輸出信息}
}void Save2File(CList& list)//將數據保存到文件
{SNode* listHead = list.GetListHead();//獲取到鏈表頭結點if(listHead == NULL){return;}ofstream fout(FILE_PATH,ios_base::binary);//不存在則創建,存在則會清空。//fout.clear();//清空文件數據SNode* p = listHead->next;while(p !=NULL ){fout<<p->stu.ToString()<<" ";//以空格分隔數據p = p->next;}fout.close();//關閉流return;
}void Read4File(CList& list)//讀取文件數據 到鏈表中
{SNode node;int beforeId = -1;//上一個idint id = -1;//臨時存放學號string name = "";//臨時存放姓名string _class = "";//存放班級float score=0;ifstream fin;fin.open(FILE_PATH, ios_base::in);//打開文件if(fin == NULL)//文件不存在,直接返回{return;}while(!fin.eof())//循環讀取直到文件末尾{fin>>id>>name>>_class>>score;if(id>0 && id != beforeId)//因為空格的原因 讀取讀后一個數據兩次,這里使用beforeId來避免重復添加{node.stu.SetId(id);node.stu.SetName(name);node.stu.SetClass(_class);node.stu.SetScore(score);list.AddTail(node);//添加}beforeId = id;//記錄上一次id}fin.close();//關閉文件流return;
}void ClearFileData()//清空文件數據,方便測試
{char isSure = 'n';//是否確認清除數據cout<<"確認清除文件數據?(y/n):";cin>>isSure;if(isSure == 'Y' || isSure == 'y'){ofstream fout(FILE_PATH);//不存在則創建,存在則會清空fout.close();cout<<"清除文件數據成功!"<<endl;system("pause");}
}void SortMenu()//排序菜單
{cout<<"┏━━━━━━━━━━┓"<<endl;cout<<"┃ 排序菜單 ┃"<<endl;cout<<"┃ 【1】 按學號排序 ┃"<<endl;cout<<"┃ 【2】 按姓名排序 ┃"<<endl;cout<<"┃ 【3】 按班級排序 ┃"<<endl;cout<<"┃ 【4】 按分數排序 ┃"<<endl;cout<<"┃ 【0】 返回 ┃"<<endl;cout<<"┗━━━━━━━━━━┛"<<endl;cout<<" ******請輸入0~4:";
}void Sort(CList& list)
{char isSave = 'n';//是否將排序后的數據更新到文件int choice = -1;while(true){system("cls");//清屏SortMenu();cin>>choice;switch(choice){case 1://按學號排序case 2://按姓名排序case 3:case 4://按班級排序list.Sort(choice-1);if(choice == 1){cout<<"***按學號升序排序如下:"<<endl;}else if(choice == 2){cout<<"***按姓名升序排序如下:"<<endl;}else if(choice == 3){cout<<"***按班級升序排序如下:"<<endl;}else if(choice == 4){cout<<"***按分數升序排序如下:"<<endl;}cout<<"序號t學號 姓名 班級 分數"<<endl;list.DisplayListData();//顯示cout<<"是否將排序后的數據更新到文件?(y/n):";cin>>isSave;if(isSave == 'Y' || isSave == 'y')//確認保存到文件{Save2File(list);//將數據重新寫入到文件cout<<"保存數據成功!"<<endl;system("pause");}else{list.Clear();//清空鏈表數據Read4File(list);//重新加載數據文件}break;case 0:return;break;default:cout<<"請輸入0~3"<<endl;system("pause");break;}}
}void MainMenu()//主菜單
{cout<<"┏━━━━━━━━┓"<<endl;cout<<"┃學生信息管理程序┃"<<endl;cout<<"┃ 【1】 顯示 ┃"<<endl;cout<<"┃ 【2】 添加 ┃"<<endl;cout<<"┃ 【3】 查找 ┃"<<endl;cout<<"┃ 【4】 修改 ┃"<<endl;cout<<"┃ 【5】 排序 ┃"<<endl;cout<<"┃ 【6】 刪除 ┃"<<endl;cout<<"┃ 【7】 清空 ┃"<<endl;cout<<"┃ 【0】 退出 ┃"<<endl;cout<<"┗━━━━━━━━┛"<<endl;cout<<" *****請輸入0~7:";
}
node.h
//鏈表節點
typedef struct SNode
{Student stu;//數據域struct SNode* next;//指針域SNode()//無參構造函數{stu.SetId(0);next = NULL;}SNode(int id)//有參構造函數{stu.SetId(id);next = NULL;}
}SNode;
student.h
//學生類
#include <sstream>
using namespace std;//int轉string
class Student
{
private:int m_id;//學號string m_name;//姓名string m_class;//班級float m_score;
public:Student()//無參構造函數{m_id = 0;m_score=0;m_name = "0";m_class = "0";}Student(int id, string name, string _class,float score)//有參構造函數,class是關鍵字,所以不能用作變量名{if(id < 0)//確保id不為負數{id = 0;}this->m_id = id;if(name.empty())//確保name不為空{name = "0";}this->m_name = name;if(_class.empty())//確保_class不為空{_class = "0";}this->m_class = _class;if(score<0)//確保_class不為空{score = 0;}this->m_score = score;}void SetId(int id)//設置id{if(id < 0 )//確保id>0,id=0為無效{id = 0;}this->m_id = id;}int GetId()//獲取id{return this->m_id;}void SetName(string name)//設置姓名{if(name.empty())//確保name不為空{name = "0";}this->m_name = name;}string GetName()//獲取姓名{return this->m_name;}void SetClass(string _class)//設置班級{if(_class.empty())//確保_class不為空{_class = "0";}this->m_class = _class;}string GetClass()//獲取班級{return this->m_class;}void SetScore(float score)//設置id{if(score < 0 )//確保id>0,id=0為無效{score = 0;}this->m_score = score;}float GetScore()//獲取id{return this->m_score;}string ToString()//將數據轉為字符串形式,方便存到文件中{stringstream ss;ss<<m_id<<" "<<m_name<<" "<<m_class<<" "<<m_score;//學號 姓名 班級return ss.str();}
};
使用GCC編譯。