最近終于寫了一個讓自己滿意的系統,我在這里分享一下,順便總結一下自己的學習心得。
1.需求分析 聽的好像是要做項目一樣,但是無論寫什么程序,些什么系統,都是要知道自己要干什么,要完成什么工作,實現那些功能,在這前列出一個表格,或是思維導圖,給自己一個方向,先規劃好再寫,不然會拉下很多東西,在我寫這個系統之前,我在圖書館的借書頁面,看了將近兩個小時,中途又看了好多次,這次代碼不能說是一個完美可以當作工程性的使用,其中還有很多測試環節,還有部分功能沒有實現,比如二次檢索,三次檢索功能,數據少得可憐,肯定還有一些未知的錯誤,所以我在這里真是分享我寫代碼,及調試代碼的方法跟過程。 2.寫代碼+調試代碼 寫代碼的時候一定要寫一個功能調試一個功能,所謂的一個功能不是一個類,而是一個類的一個函數,如果一個函數會影響到其他函數的運行,不調好之前的函數,現在的函數也沒法運行,當代碼隨著項目的增大,代碼長度幾何增長是,再找錯誤就很難的了,所以順著調試下去,以便你寫完的代碼是可以運行的,是正確的,而具體能否實現功能在另說。 數據類與操作類的分離,面向對象要的是封裝性,操作抽象+數據抽象,繼承,寫代碼寫完能夠復用最好,亂糟糟的寫完不能復用的類扔在那里,以后再也不會用到,浪費時間,完全可以寫一些代碼條理清晰,更重要的是,下次相似的代碼不用再繼續寫,這應該是應該具備的素養。 以下是我調試代碼的過程,最后代碼還是有一點錯誤,這里是我的明明還是不好的原因,補充一下我認為明明一定要有意義,可以將學生的每科學分定義為a b c d. …也可以定義為數學 英語 物理 c++…這樣可以增加代碼的可讀性。 引以為戒: 下文中這兩個MAP混用導致了一些問題,以至于我交代碼的時候是錯誤的還有沒有發現
map<string,int>idtorea; //讀者id對應讀者數據下標
map<string ,int> idtoob; //圖書id對應圖書數據下標
時間類 時間類第一次調試運行,測試有參無參,重載<< ,>>和+
寫到后邊發現,自己重載的+錯了,而且還需要計算兩個時間類相差的時間,回頭從新寫的重載+,跟-
圖書類 這里調試很多遍,開始留了一個應還時間Time類,后來發現,沒有用。 后來想到,可能查詢歸還時間,所以寫了get函數,但是函數不能反回局部類對象,只好寫成static。 因為后邊的時候需要輸出,但是有些數據只有管理員能夠看到,所以寫完后邊的回來寫的print函數。 讀者類 這里學生能做的事情不多,修改密碼,查詢個人信息,別的都做不了。
在后邊實現借書就要在數據類中實現更改,所以在這里加了一條進行測試所添加的操作。 操作數據類 每一條新數據都必須,擁有參初始化,除了文件讀取除外。 操作類也面臨著不能直接輸出的尷尬境界,所以回來,再寫一個print。 終于看到自己的程序成功運行,也試了幾組錯誤情況。基本無問題。
#include<bits/stdc++.h.>
using namespace std;
class Time
{int year,month,day;
public:Time(){loadtime();}Time(int y,int m,int d):year(y),month(m),day(d){}; //用與圖書出版日期等已知數據的對象的初始化;//不能創建圖書對象,有參初始化就沒意義。// Time(Time & a){year=a.year,month=a.month,day=a.day;} //用一個時間類初始化一個時間類,為后續操作準備;//這句不注釋就沒法運行,不得解void loadtime(); //定義時間獲取函數,學生借書的時間不可更改,直接從系統讀入;friend istream & operator>>(istream &in,Time & a); //不設置set函數,時間直接一次性全部修改即可;friend stringstream & operator>>(stringstream &in,Time & a);friend ostream & operator<<(ostream &out,Time & a);bool operator <(const Time &d)const{ //重載小于號,用于數據時間排序,不需要修改數據const;return year!=d.year?year<d.year:month!=d.month?month<d.month:day<d.day;}int judge() const; //判斷是否為閏年,用于續借日期的變化;int judge(int year) const ;//寫一個有參的判斷函數;Time operator +(int a) ; //重載加號,用于續借日期的變化;friend int operator -(Time a,Time b); //計算兩段時間間隔;
};
Time Time::operator +(int a)
{int m[] = {0,31,28,31,30,31,30,31,31,30,31,30,31};day+=a;int flag=1;while(day>m[month]){if(month==2){if(day>m[month]+judge()){day-=m[month]+judge();month++;}}else {day=day-m[month];month++;}//因為一對大括號跑了好幾遍,敲ACM也一樣,不要偷懶if(month>12){month-=12;year++;}}
}
int operator -(Time a,Time b)
{int monthdays[2][12] = { { 31,28,31,30,31,30,31,31,30,31,30,31 },{ 31,29,31,30,31,30,31,31,30,31,30,31 } };int yeardays[2] = { 365,366 };int sumdays=0;if (a.year == b.year&& a.month == b.month){sumdays = b.day - a.day;}elseif (a.year == b.year){sumdays += monthdays[a.judge(a.year)][a.month-1] - a.day;for (int i = a.month; i < b.month-1; i++)sumdays += monthdays[a.judge(a.year)][i];sumdays += b.day;}else{sumdays += monthdays[a.judge(a.year)][a.month-1] - a.day;for (int i = a.month; i < 12; i++)sumdays += monthdays[a.judge(a.year)][i];for (int i = a.year + 1; i < b.year; i++)sumdays += yeardays[a.judge(i)];for (int i = 0; i < b.month - 1; i++)sumdays += monthdays[a.judge(b.year)][i];sumdays += b.day;}return sumdays;
}
int Time::judge() const{if(year % 4 == 0 && year %100 != 0 ||year % 400 == 0) return 1;else return 0;
}
int Time::judge(int year) const{if (year % 4 == 0 && year % 100 != 0 || year % 400 == 0)return 1;else return 0;
}
void Time::loadtime(){time_t rawtime;struct tm *ptminfo;time(&rawtime);ptminfo = localtime(&rawtime);year=ptminfo->tm_year + 1900;month=ptminfo->tm_mon + 1;day=ptminfo->tm_mday;
}
istream & operator>>(istream &in,Time & a){in>>a.year>>a.month>>a.day;return in;
}
ostream & operator<<(ostream &out,Time & a)
{out<<a.year<<" "<<a.month<<" "<<a.day<<" ";return out;
}
stringstream & operator>>(stringstream &in,Time & a){in>>a.year>>a.month>>a.day;return in;
}
/*
int main()
{Time demo1;//無參初始化對象cout<<demo1<<endl;Time demo2(demo1);//有參初始化對象,便于不同時間定義對象,時間不同;cout<<demo2<<endl;demo2+60;//為續借,即還書時間做準備;cout<<demo2;Time demo3(2000,03,19);cout<<demo3<<endl;
}
*/
/*
int main()
{Time demo1,demo2;cin>>demo1>>demo2;int d=demo1-demo2;demo1+d;cout<<demo1<<endl;cout<<d<<endl;
}*/
class Book
{string name;string press; //出版社string pubtime; //出版時間通常在圖書館只有年份string author; //作者string suoshu; //索書號string id; //每本書都有唯一的條形碼,兩本完全一樣的書,在這里應該看作兩本書string locate;string jsr; //指向借書人數據在的位置的下標(-1),代表可借int fk; //每本書都有自己的罰款,不會影響其他書籍,定義在這里比定義在讀者類要合適bool xj; //比起寫入記錄中查詢,寫在圖書中,無論是還書,還是續借,都更加便捷Time jy;// Time rebac;
public:Book():name(""),press(""),author(""),id(""),suoshu(""),locate(""),jsr("-1"),fk(0){}//學生端不能創建書籍對象,只寫一個無參初始化,用于讀取文件數據;string getname ()const{return name;}string getpress ()const{return press;}string getauthor ( )const{return author;}string getpubtime ( )const{return pubtime;}string getid ( )const{return id;}string getsuoshu ( )const{return suoshu;} //通過上述get函數為下面的查詢做準備;int getfk(){jsfk();return fk;}void xxj(){/*if(fk<=0)xj=!xj;else cout<<"請先繳清罰款"<<endl;*/ //改為在讀者類判斷,不只是一本書的罰款,會影響借書;xj=!xj;}bool getxj(){ return xj;}void js(string idcard){jsr=idcard;} //學號跟圖書的條形碼是唯一的,由此來對應;Time& getreback();void jsfk();void print();friend istream & operator>>(istream &in,Book & a);friend ostream & operator<<(ostream &out,Book & a);
};
void Book::jsfk()
{int brr;if(xj) brr=120;else brr=60;Time tem;fk=tem-jy-brr;if(fk<0) fk=0;
}
void Book::print()
{cout<<name<<" "<<press<<" "<<author<<" "<<id<<" "<<suoshu<<" "<<locate<<" ";if(jsr!="-1") cout<<"已借出 歸還時間:"<<getreback()<<endl;else cout<<endl;
}
Time& Book::getreback(){static Time tem(jy);tem+60*(1+getxj());return tem;
}
istream & operator>>(istream &in,Book & a){in>>a.name>>a.press>>a.pubtime>>a.author>>a.suoshu>>a.id>>a.jsr>>a.locate>>a.jy>>a.xj;return in;
}
ostream & operator<<(ostream &out,Book & a){out<<a.name<<" "<<a.press<<" "<<a.pubtime<<" "<<a.author<<" "<<a.suoshu<<" "<<a.id<<" "<<a.jsr<<" "<<a.locate<<" "<<a.jy<<" "<<a.xj;return out;
}
//記 北京機械工業出版社 2016 胡凡 TP301.6/H569 01664298 123456 -1 采編部在編 2018 5 16 1
/*
int main()
{Book demo;cin>>demo;cout<<demo;cout<<demo.getname()<<endl;cout<<demo.getpress()<<endl;cout<<demo.getauthor()<<endl;cout<<demo.getsuoshu()<<endl;cout<<demo.getpubtime()<<endl;cout<<demo.getfk()<<endl;int jsr;cin>>jsr;demo.js(jsr);cout<<demo.getxj()<<endl;demo.xxj();cout<<demo.getxj()<<endl;cout<<demo<<endl;
} //算法筆記 北京機械工業出版社 2016 胡凡 TP301.6/H569 01664298 123 采編部在編 2018 5 16 1
*/
/*
int main()
{Book demo;cin>>demo;cout<<demo.getreback();
}*/
/*
int main()
{Book demo1;//無參初始化對象cin>>demo1;demo1.print();
}
*/
class Student
{string name;string id;string key;string mail;vector<string> jy;/*按時間先后借的書,則為有序,int是圖書數據的ID;通過下標聯通了圖書與讀者。*/int yj;//已借圖書
public:Student() :name(""),id(""),key(""),mail(""){jy.clear();}//void printxx() 想寫打印信息的功能,但是目前這個類看不到圖書數據,無法關聯。轉而寫get函數;vector<string> getjy() const{return jy;} //先返回一個vector對象,目前看不到圖書數據,所以返回后,在操作類中使用string getname(){return name;}string getid(){return id;}string getkey(){return key;}string getmail(){return mail;}int getyj()const {return yj;}void setkey(string tem) ; //修改密碼void jieyue(string obid); //借閱圖書,圖書館的借閱最后都是按照書的唯一的條碼來借閱void reback(string obid); //歸還同上。/*現在看不到圖書數據,只能寫出部分借閱,歸還操作,在操作類中應判斷是否具有罰款,此函數僅用于修改學生,作為子函數使用*/friend istream & operator>>(istream &in,Student & a);friend ostream & operator<<(ostream &out,Student & a);
} ;
istream & operator>>(istream &in,Student & a)
{in>>a.name>>a.id>>a.key>>a.mail>>a.yj;string tem;for(int i=0;i<a.yj;i++) {in>>tem;a.jy.push_back(tem);}return in;
}
ostream & operator<<(ostream &out,Student & a)
{out<<a.name<<" "<<a.id<<" "<<a.key<<" "<<a.mail<<" "<<a.yj<<" ";for(int i=0;i<a.yj;i++) cout<<a.jy[i]<<" ";return out;
}
void Student::jieyue(string obid)
{if(yj>=10) cout<<"借閱數量已達上限"<<endl;else jy.push_back(obid);yj=jy.size();
}
void Student::reback(string obid) //歸還操作很寬泛,甚至都不需要登陸賬號,但是根據圖書找到人,最后還是要根據id在這人身上去掉
{//不需要容錯,如果系統不崩潰,從書籍查借人一定是唯一的auto po=find(jy.begin(),jy.end(),obid);if(po==jy.end()) cout<<"還書失敗,請聯系管理員"<<endl;else jy.erase(po);yj=jy.size();
}
void Student::setkey(string tem)
{while(tem!=key){cout<<"密碼錯誤,請重試"<<endl;cin>>tem;}cin>>tem;key=tem;
}
/*
int main()
{Student demo;cin>>demo;cout<<demo.getname()<<endl;cout<<demo.getid()<<endl;cout<<demo.getkey()<<endl;cout<<demo.getmail()<<endl;cout<<demo.getyj()<<endl;cout<<demo;
}*/
//張俊浩 2018212513 123456 529934209@qq.com 1 203
/*
int main()
{string tem;Student demo;cin>>demo>>tem;demo.jieyue(tem);cout<<demo<<endl;cin>>tem;demo.reback(tem);cout<<demo;
}
*/class Operate //記錄只能生成不能修改
{Time time;string oper; //操作string peo; //操作人idstring boo; //圖書對象IDint fk; //當操作為還書時有真實罰款,其余為-1
public:Operate( ):oper(""),peo(""),boo(""),fk(-1){} //僅用于文件讀寫Operate(string o,string p,string b,int c):oper(o),peo(p),boo(b),fk(c){time.loadtime();} //操作無論管理員,學生都無法改變時間;string getname(){return peo;}string getbook(){return boo;}string getoper(){return oper;}int getfk(){return fk;} // 用于后續查詢操作void print() ;friend istream & operator>>(istream &in,Operate & a);friend ostream & operator<<(ostream &out,Operate & a);
} ;
void Operate::print()
{cout<<time<<" "<<peo<<" "<<oper<<" "<<boo<<" ";if(fk!=-1) cout<<"繳納罰款:"<<fk<<endl;
}
istream & operator>>(istream &in,Operate & a)
{in>>a.time>>a.peo>>a.oper>>a.boo>>a.fk;return in;
}
ostream & operator<<(ostream &out,Operate & a)
{out<<a.time<<" "<<a.peo<<" "<<a.oper<<" "<<a.boo<<" "<<a.fk<<" ";return out;
}
/*
int main()
{Operate demo;cin>>demo;cout<<demo.getname()<<" "<<demo.getoper()<<" "<<demo.getbook()<<" "<<demo.getfk()<<endl;cout<<demo<<endl;string name,op,ob;int fk;cin>>name>>op>>ob>>fk;Operate demo2(name,op,ob,fk);cout<<demo2<<endl;
}
*/
/*
int main()
{Operate demo;cin>>demo;demo.print();
}*/
class Library
{string account;string password; //每次登入圖書館進行操作都要有賬號密碼vector<Book> book;vector<Student> reader;vector<Operate> record; //三個基礎數據;//圖書查詢操作所需數據multimap<string,int> pubtimque; //出版時間multimap<string,int> suoshuque; // 索書號multimap<string,int> pressque; //出版社//書名與作者都需要模糊查詢//數據查詢map<string,int>idtorea; //讀者id對應讀者數據下標map<string ,int> idtoob; //圖書id對應圖書數據下標multimap<string,int> ridtorec; //讀者Id對應操作數據下標multimap<string,int> bidtorec; //圖書 id對應操作數據下標
public:Library(string ac,string pass): account(ac),password(pass){load();login();cout<<book.size();}void login();//書籍查詢操作void querysm(string name) ;//書名查詢void queryss(string suoshu) ; //索書號查詢void queryath(string ath); //作者查詢void querypres(string pre); //出版社查詢void querytim(string pub);//出版時間查詢//個人信息操作void quepers(); //查詢讀者身份信息void quebrro();//查詢借閱信息void queop(); //查詢讀者操作記錄(僅個人)//基礎操作int cxkj(); //查詢課可借書的數量void jieshu(string id) ;void huanshu(string id);void xujie(string id); //圖書館雖然不用輸入書的條碼,但是現在也是通過書的磁獲取//也應該看是輸入,比如某些地方仍用掃碼,甚至手輸void load();void save();~Library(){save();}
};
//有些map是給管理端用的,這里只寫不讀;
void Library::login()
{while(1){auto po=idtorea.find(account);if(po!=idtorea.end()&&reader[po->second].getkey()==password) break;cout<<"賬號密碼不匹配\n請重新輸入\n"; //可以在分個賬號不存在,但看很多網站,//都不會報不存在,為了提高一點安全性;cin>>account>>password;}cout<<"登陸成功\n";
}
void Library:: querysm(string name)
{for(auto po=book.begin();po!=book.end();po++){auto m=po->getname().find(name);if(m!=-1) po->print();}
}
void Library:: queryss(string suoshu)
{auto beg=suoshuque.lower_bound(suoshu);auto en=suoshuque.upper_bound(suoshu);for(auto po=beg;po!=en;po++)book[po->second].print();
}
void Library:: queryath(string ath){for(auto po=book.begin();po!=book.end();po++){auto m=po->getauthor().find(ath);if(m!=-1) po->print();}
}
void Library:: querypres(string pre)
{auto beg=pressque.lower_bound(pre);auto en=pressque.upper_bound(pre);for(auto po=beg;po!=en;po++) book[po->second].print();
}
void Library:: querytim(string pub)
{auto beg=pubtimque.lower_bound(pub);auto en=pubtimque.upper_bound(pub);for(auto po=beg;po!=en;po++)book[po->second].print();
}
void Library:: quepers(){cout<<reader[idtoob[account]].getname()<<" ";cout<<reader[idtoob[account]].getid()<<" ";cout<<reader[idtoob[account]].getmail()<<" ";cout<<reader[idtoob[account]].getyj()<<" ";cout<<cxkj()<<endl;
}
void Library:: quebrro()
{for(auto po=reader[idtoob[account]].getjy().begin();po!=reader[idtoob[account]].getjy().end();po++)book[idtoob[ *po]].print();
}
void Library:: queop()
{auto beg=ridtorec.lower_bound(account);auto en=ridtorec.upper_bound(account);for(auto po=beg;po!=en;po++)record[po->second].print();
}
int Library:: cxkj()
{int ans=0;for(auto po=reader[idtoob[account]].getjy().begin();po!=reader[idtoob[account]].getjy().end();po++)ans+=book[idtoob[ *po]].getfk();if(ans>0) return -1;else return 10-reader[idtoob[account]].getjy().size();
}
void Library:: jieshu(string id)
{if(cxkj()==-1){ cout<<"歸還逾期,請先歸還\n"; return ;}else if(cxkj()==0) { cout<<"達到借書上限\n"; return ;}reader[idtorea[account]].jieyue(id);book[idtoob[id]].js(account);Operate tem("借書",account,id,-1);record.push_back(tem);ridtorec.insert(make_pair(account,record.size()-1));bidtorec.insert(make_pair(id,record.size()-1));
}
void Library:: huanshu(string id)
{reader[idtorea[account]].reback(id);//異常在 reback拋出book[idtoob[id]].js("-1");int money=book[idtoob[id]].getfk();Operate www("還書",account,id,money);record.push_back(www);ridtorec.insert(make_pair(account,record.size()-1));bidtorec.insert(make_pair(id,record.size()-1));
}
void Library:: xujie(string id)
{if(cxkj()==-1){ cout<<"歸還逾期,請先歸還\n"; return ;}else if(cxkj()==0) { cout<<"達到借書上限\n"; return ;}book[idtoob[id]].xxj();Operate tem("續借",account,id,-1);record.push_back(tem);ridtorec.insert(make_pair(account,record.size()-1));bidtorec.insert(make_pair(id,record.size()-1));
}
void Library::save()
{ofstream out1("d:\\book.txt",ios::out);for(auto po=book.begin(); po!=book.end(); po++)out1<<*po<<endl;out1.close();ofstream out2("d:\\reader.txt",ios::out);for(auto po=reader.begin(); po!=reader.end(); po++)out2<<*po<<endl;out2.close();ofstream out3("d:\\record.txt",ios::out);for(auto po=record.begin(); po!=record.end(); po++)out3<<*po<<endl;out3.close();
}
void Library:: load()
{ifstream in1("d:\\book.txt",ios::in);if(in1){Book tem1;book.clear();while(in1>>tem1){book.push_back(tem1);idtorea.insert(make_pair(tem1.getid(),book.size()-1));pubtimque.insert(make_pair(tem1.getpubtime(),book.size()-1));suoshuque.insert(make_pair(tem1.getsuoshu(),book.size()-1));pressque.insert(make_pair(tem1.getpress(),book.size()-1));}in1.close();}ifstream in2("d:\\reader.txt",ios::in);if(in2){reader.clear();Student tem2;while(in2>>tem2){reader.push_back(tem2);idtorea.insert(make_pair(tem2.getid(),reader.size()-1));}in2.close();}ifstream in3("d:\\record.txt",ios::in);if(in3){record.clear();Operate tem3;while( in3>>tem3){record.push_back(tem3);ridtorec.insert(make_pair(tem3.getname(),record.size()-1));bidtorec.insert(make_pair(tem3.getbook(),record.size()-1));}in3.close();}
}
int main()
{string account,key,name,suoshu,ath,pre,pub,id;cin>>account>>key;Library demo(account,key);cin>>name;demo. querysm( name) ;//測試書名查詢cin>>suoshu;demo. queryss( suoshu) ; //測試索書號查詢cin>>ath;demo. queryath( ath); //測試作者查詢cin>>pre;demo. querypres( pre); //測試出版社查詢cin>>pub;demo. querytim( pub);//測試出版時間查詢//測試個人信息操作demo. quepers(); //測試查詢讀者身份信息demo. quebrro();//測試查詢借閱信息demo. queop(); //測試查詢讀者操作記錄(僅個人)//測試基礎操作demo. cxkj(); //測試查詢課可借書的數量cin>>id;demo. jieshu( id) ;cin>>id;demo. huanshu( id);cin>>id;demo. xujie( id);return 0;
}
總結
以上是生活随笔 為你收集整理的图书馆管理系统用户端心得 的全部內容,希望文章能夠幫你解決所遇到的問題。
如果覺得生活随笔 網站內容還不錯,歡迎將生活随笔 推薦給好友。