软件开发与创新 第二周实验
项目来源于 大一上的程序设计基础的期末大作业 用C语言实现《网上购书系统》通过阅读分析源码找出软件尚存的缺陷 改进其软件做二次开发
改程序正常启动程序后,显示所有库存商品,能够正常显示所有库存,添加新的商品入库,将商品加入购物车,结算,修改库存等功能。
#include <iostream> using namespace std; #include <string> #include <sstream> #include <vector> #include <fstream> using namespace std; class Goods { public: Goods(string t, double pr):title(t),price(pr) {} Goods(){} virtual ~Goods() {} virtual double getPrice() { return price; } virtual string getTitle() { return title; } virtual string getDetails()=0; virtual bool Init(ifstream &infile) = 0; //从文件流中init virtual bool Init(string press){ return true; }; //从控制台输入变量,函数重载 virtual bool SaveToFile(ofstream &outfile) = 0; public: string title; //名称 double price; string press; //id 扫描仪 }; class Book : public Goods { public: Book(string t, double pr):Goods(t,pr) { author ="Unknown"; press = "Unknown"; ISBN = "Unknown"; } Book() { } ~Book() {} void setDetails(string au, string pr, string isbn) { author = au; press = pr; ISBN = isbn; } string getDetails() { ostringstream os; os<<"Title:"<<getTitle()<<" "; os<<"Author:"<<author<<" "; os<<"Press:"<<press<<" "; os<<"ISBN:"<<ISBN<<" "; os<<"Price:"<<getPrice()<<endl; return os.str(); } bool Init(ifstream &infile) { //infile>>press; infile>>ISBN; infile>>title; infile>>author; infile>>publish; infile>>price; //infile>>iStoreNum; return true; } bool Init(string strPress) { cout << "输入ISBN号" << endl; press = strPress; cin>>ISBN; cout << "输入名称" << endl; cin>>title; cout << "输入作者" << endl; cin>>author; cout << "输入出版社" << endl; cin>>publish; cout << "输入价格" << endl; cin>>price; return true; }; bool SaveToFile(ofstream &outfile) { outfile<<press<< " "; outfile<<ISBN<< " "; outfile<<title<< " "; outfile<<author<< " "; outfile<<publish<< " "; outfile<<price<< endl; return true; } private: string author; string ISBN; string publish; }; //杂志 class Magazine : public Goods { public: Magazine(string t, double pr):Goods(t,pr) { issue = "Unknown"; issNo = "Unknown"; period = "Unknown"; } Magazine() {} ~Magazine() {} void setDetails(string isn, string p,string is) { issue = is; issNo = isn; period = p; } string getDetails() { ostringstream os; os<<"Title:"<<getTitle()<<" "; os<<"IssueNo.:"<<issNo<<" "; os<<"Period:"<<period<<" "; os<<"Issue:"<<issue<<" "; os<<"Price:"<<getPrice()<<endl; return os.str(); } //maga000001 CN11-2697/TP 文艺生活 每月 10期 11.5 bool Init(ifstream &infile) { infile>>issNo; infile>>title; infile>>period; infile>>issue; infile>>price; return true; } bool Init(string strPress) { press = strPress; cout << "输入期刊号" << endl; cin>>issNo; cout << "输入名称" << endl; cin>>title; cout << "输入期刊周期" << endl; cin>>period; cout << "输入期刊号" << endl; cin>>issue; cout << "输入价格" << endl; cin>>price; return true; }; bool SaveToFile(ofstream &outfile) { outfile<<press<< " "; outfile<< issNo<< " " ; outfile<< title<< " " ; outfile<< period<< " " ; outfile<< issue<< " " ; outfile<< price<<endl; return true; } private: string issue; //期号 string issNo; string period; }; class MusicCD : public Goods { public: MusicCD(string t, double p):Goods(t,p) { player = "Unknown"; style = "Unknown"; tracks = 0; lasttime = 0; } MusicCD() {} ~MusicCD() {} void setDetails(string p, string st,int tr, int t) { player = p; style = st; tracks = tr; lasttime = t; } string getDetails() { ostringstream os; os<<"Title:"<<getTitle()<<" "; os<<"Player:"<<player<<" "; os<<"Style:"<<style<<" "; os<<"Tracks:"<<tracks<<" "; os<<"LastTime:"<<lasttime<<"minitues "; os<<"Price:"<<getPrice()<<endl; return os.str(); } //cd000001 不再犹豫 beyond 摇滚 28 50 18.00 bool Init(ifstream &infile) { infile>>title; infile>>player; infile>>style; infile>>tracks; infile>>lasttime; infile>>price; return true; } bool Init(string strPress) { press = strPress; cout << "输入名称" << endl; cin>>title; cout << "输入歌手" << endl; cin>>player; cout << "输入风格" << endl; cin>>style; cout << "输入音轨数量" << endl; cin>>tracks; cout << "输入CD时长" << endl; cin>>lasttime; cout << "输入价格" << endl; cin>>price; return true; }; bool SaveToFile(ofstream &outfile) { outfile<<press<< " "; outfile<<title<< " "; outfile<<player<< " "; outfile<<style<< " "; outfile<<tracks<< " "; outfile<<lasttime<< " "; outfile<<price<<endl; return false; } private: string player; string style; int tracks; //音轨 int lasttime; }; class BookStoreMgr { public: bool LoadStore(); //从文件加载数据 bool SaveStore(); //保存数据 int m_iItemNum; //当前库存商品个数 void ShowAllItems(); //显示所有商品 Goods* FindStore(string strTitle); //根据名称查找商品 bool DelStoreByPress(string strPress); //根据press id查找商品 bool ChangeStore(string strPress); //修改库村商品信息 Goods* FindStoreByPress(string strPress); //查找商品 //private: vector<Goods*> items; //所有的商品列表 }; void BookStoreMgr::ShowAllItems() { vector<Goods*>::iterator itor; for (itor = items.begin(); itor != items.end(); itor++) { cout << (*itor)->getDetails() << endl; } } bool BookStoreMgr::LoadStore() { try{ std::ifstream infile("store.txt"); infile >> m_iItemNum; Goods* pGoods = NULL; for(int i=0;i < m_iItemNum;i++) { string press; infile>>press; if (press.find("book") == 0) { pGoods = new Book(); }else if (press.find("maga") == 0){ pGoods = new Magazine(); } else if (press.find("cd") == 0){ pGoods = new MusicCD(); } else if (press.find("vcd") == 0){ pGoods = new Video(); }else{ continue; } pGoods->press = press; pGoods->Init(infile); items.push_back(pGoods); } infile.close(); } catch(...){ cout << "打开文件失败!" << endl; return false; } return true; } bool BookStoreMgr::SaveStore() { std::ofstream outfile("store.txt"); outfile << m_iItemNum << std::endl; for(int i = 0; i < m_iItemNum; i++) { Goods *pGood = items[i]; pGood->SaveToFile(outfile); } outfile.close(); return true; } //可以添加修改为模糊查询 Goods* BookStoreMgr::FindStore(string strTitle) { vector<Goods*>::iterator itor; Goods *pGoods = NULL; bool bFind = false; for (itor = items.begin(); itor != items.end(); itor++) { if ((*itor)->title == strTitle) { cout << (*itor)->getDetails() << endl; pGoods = (*itor); bFind = true; return pGoods; } } cout << "找不到名称是" << strTitle << "的商品" << endl; return pGoods; } //可以添加修改为模糊查询 Goods* BookStoreMgr::FindStoreByPress(string strPress) { vector<Goods*>::iterator itor; Goods *pGoods = NULL; bool bFind = false; for (itor = items.begin(); itor != items.end(); itor++) { if ((*itor)->press == strPress) { cout << (*itor)->getDetails() << endl; pGoods = (*itor); bFind = true; return pGoods; } } cout << "找不到名称是" << strPress << "的商品" << endl; return pGoods; } bool BookStoreMgr::DelStoreByPress(string strPress) { vector<Goods*>::iterator itor; bool bFind = false; for (itor = items.begin(); itor != items.end(); itor++) { if ((*itor)->press == strPress) { cout << (*itor)->getDetails() << endl; items.erase(itor); bFind = true; m_iItemNum -= 1; SaveStore(); cout << "成功删除press id是" << strPress << "的商品" << endl; return true; } } cout << "找不到press id是" << strPress << "的商品" << endl; return false; } bool BookStoreMgr::ChangeStore(string strPress) { vector<Goods*>::iterator itor; bool bFind = false; for (itor = items.begin(); itor != items.end(); itor++) { if ((*itor)->press == strPress) { cout << (*itor)->getDetails() << endl; (*itor)->Init(strPress); bFind = true; SaveStore(); cout << "成功删除press id是" << strPress << "的商品" << endl; return true; } } cout << "找不到press id是" << strPress << "的商品" << endl; return true; } int main() { const int N = 4; Cart myCart; BookStoreMgr storeMgr; storeMgr.LoadStore(); int i = 0; while(1) { printf(" |-------------------------------------------------------------------|\n"); printf(" |*****************************欢迎使用******************************|\n"); printf(" |*******************中国图书影像制品销售管理系统********************|\n"); printf(" | 1*客户结账 |\n"); printf(" | 2*商品入库 |\n"); printf(" | 3*根据名称查询 |\n"); printf(" | 4*删除商品 |\n"); printf(" | 5*修改商品 |\n"); printf(" | 6*显示所有商品 |\n"); printf(" | 7*退出系统 |\n"); printf(" | 请选择: |\n"); printf(" |-------------------------------------------------------------------|\n"); scanf("%d",&i); switch(i)//用swich-case语句:用于枚举选择 { case 1: { Cart cart; vector<string> vecCartPress; for(;;) { cout << "请输入商品press id(输入ok结账)" << endl; string strPress; cin >> strPress; if ("ok" == strPress){ cart.goodsList(); cout << "总共需要支付: " << cart.totalPrice() << endl; //删除商品 for (int i = 0; i < vecCartPress.size(); i++) { storeMgr.DelStoreByPress(vecCartPress[i]); } break; }else{ Goods *pGoods = storeMgr.FindStoreByPress(strPress); if (NULL != pGoods) { cart.addItem(pGoods); vecCartPress.push_back(strPress); } } } } break; case 2: { //商品入库 cout << "请输入要入库的商品press ID:" << endl; cout << "如book000016, maga000005, cd000004, vcd000005" << endl; string press; cin>> press; Goods *pGoods = NULL; if (press.find("book") == 0) { pGoods = new Book(); } else if (press.find("maga") == 0) { pGoods = new Magazine(); } else if (press.find("cd") == 0) { pGoods = new MusicCD(); } else { cout << "press id格式错误,请重新输入" << endl; continue; } pGoods->Init(press); storeMgr.items.push_back(pGoods); storeMgr.m_iItemNum += 1; storeMgr.SaveStore(); } break; case 3: //根据名称查询 { // cout << "请输入名称:" << endl; string strTitle; cin >> strTitle; storeMgr.FindStore(strTitle); } break; case 4: { cout << "请输入要删除的press id:" << endl; string strPress; cin >> strPress; storeMgr.DelStoreByPress(strPress); } break; case 5: { cout << "请输入要修改的商品press id:" << endl; string strPress; cin >> strPress; storeMgr.ChangeStore(strPress); } break; case 6: { storeMgr.ShowAllItems(); } break; case 7: { exit(0); } break; default: { break; } } }; char ch; cin >> ch; }
Goods是商品基类,BookMagazine,MusicCD是子类。
BookStoreMgr是控制类,是面向对象的借口,封装了增删查改的操作并使用vector保存了所有的商品信息。
bool LoadStore(); //从文件加载数据
bool SaveStore(); //保存数据
int m_iItemNum; //当前库存商品个数
void ShowAllItems(); //显示所有商品
Goods* FindStore(string strTitle); //根据名称查找商品
bool DelStoreByPress(string strPress); //根据press id查找商品
bool ChangeStore(string strPress); //修改库村商品信息
Goods* FindStoreByPress(string strPress); //查找商品
private:
vector<Goods*> items; //所有的商品列表
};
由于这个项目作为网上购书系统,适当应该从图书类商品拓展到类似于影像、碟片等商品。
所以在这边新加了 一个子类Video 类似的也可以添加别的更多门类的商品
class Video : public Goods { public: Video(string t, double p):Goods(t,p) { description = "Unknown"; lasttime = 0; } Video() {} ~Video() {} void setDetails(int t, string des) { description = des; lasttime = t; } string getDetails() { ostringstream os; os<<"Title:"<<getTitle()<<" "; os<<"Description:"<<description<<" "; os<<"LastTime:"<<lasttime<<"minitues "; os<<"Price:"<<getPrice()<<endl; return os.str(); } //vcd000001 笑傲江湖 168 10.00 令狐冲和东方不怕的故事 bool Init(ifstream &infile) { infile>>title; infile>>lasttime; infile>>price; infile>>description; return true; } bool Init(string strPress) { press = strPress; cout << "输入名称" << endl; cin>>title; cout << "输入VCD时长" << endl; cin>>lasttime; cout << "输入价格" << endl; cin>>price; cout << "输入描述(不要有空格)" << endl; cin>>description; return true; }; bool SaveToFile(ofstream &outfile) { outfile<<press<< " "; outfile<<title<< " " ; outfile<<lasttime<< " " ; outfile<<price<< " " ; outfile<<description<<endl ; return true; } private: string description; int lasttime; //分钟 }; class Cart { public: Cart() {} ~Cart() {} void addItem(Goods* g) { items.push_back(g); } double totalPrice() { double total = 0; for(unsigned int i=0; i<items.size(); i++) total += items[i]->getPrice(); return total; } string goodsList() { string itemslist = ""; for(unsigned int i=0; i<items.size(); i++) itemslist += items[i]->getDetails(); return itemslist; } private: vector<Goods*> items; }; else if (press.find("vcd") == 0) { pGoods = new Video(); }
这样已经可以添加video门类 本程序还有进行进一步优化 例如可以只展示部分的商品信息 隐藏刊号、cd时长等