课程设计任务书
2011—2012学年第1学期
电子与信息工程系计算机科学与技术专业班级
课程设计名称:数据结构课程设计
设计题目:库存管理系统
完成期限:自2012 年 1 月2日至2012 年 1 月 6 日共 1 周
设计依据、要求及主要内容(可另加附页):
一、设计目的
熟悉各种数据结构和运算,会使用数据结构的基本操作解决一些实际问题。
二、设计要求
(1)重视课程设计环节,用严谨、科学和踏实的工作态度对待课程设计的每一项任务;
(2)按照课程设计的题目要求,独立地完成各项任务,严禁抄袭;凡发现抄袭,抄袭者与被抄袭者皆以零分计入本课程设计成绩。凡发现实验报告或源程序雷同,涉及的全部人员皆以零分计入本课程设计成绩;
(3)学生在接受设计任务后,首先要按设计任务书的要求编写设计进程表;
(4)认真编写课程设计报告。
三、设计内容
1)问题描述
试设计一库存管理系统,产品信息包括产品编号、名称、价格、数量等(产品编号不重复)。
2) 基本要求
该系统应具有以下功能:
1、产品信息录入功能(产品信息用文件保存)--输入
2、产品信息浏览功能--输出
3、产品入库
4、产品出库
5、查询和排序功能:
1)按价格从大到小排序
2)按名称查询
6、产品信息删除、修改功能。
四、参考文献
[1]《数据结构》. 王红梅. 清华大学出版社
[2]《数据结构学习辅导与实验指导》. 王红梅. 清华大学出版社
[3]《C++程序设计》. 钱能. 清华大学出版社
[4]《C++程序设计试验指导》. 钱能. 清华大学出版社
[5]《C++程序设计》.谭浩强. 清华大学出版社
#include
#include
#include
#include
using namespace std;
int count=0;
class CData //定义数据基类
{
public:
CData(){};
virtual int Compare(CData &)=0;
virtual void Show()=0;
virtual ~CData(){};
};
class CNode //定义结点基类
{
private:
CData *pData; //用于指向数据类的指针
CNode *pNext; //用于指向链表的后向指针
public:
void InputData(CData *pdata){pData=pdata;} //输入数据
void ShowNode(){pData->Show();} //打印一个节点的数据
CData *GetData(){return pData;}
friend class CList; //定义链表类为基类
};
class CList
{
CNode *pHead; //链表头结点指针
public:
CList(){pHead=0;};
~CList(){DeleteList();}
void AddNode(CNode *pnode); //在首部添加结点
CNode *DeleteNode(CNode *); //删除一个指定的结点,返回该结点的指针
CNode *Search(CData &); //查找一个指定的数据,返回该数据所在的结点在链表的指针,未找到返回0
bool IsExist(CData &);
void ShowList(); //打印整个链表
void DeleteList(); //删除整个链表
CNode *GetListHead(){return pHead;} //返回链表首结点
CNode *GetListNextNode(CNode *pnode); //返回链表指定结点的下一个结点
};
CNode *CList::GetListNextNode(CNode *pnode) //返回链表指定结点的下一个结点
{
CNode *p1=pnode;
return p1->pNext;
};
void CList::AddNode(CNode *pnode) //在首部添加结点
{
if (pHead==0) //如果是空链表,插入的结点是唯一的结点
{
pHead=pnode;
pnode->pNext=0;
return;
}
else //否则,插入到链表首部
{
pnode->pNext=pHead;
pHead=pnode;
}
};
CNode *CList::DeleteNode(CNode *pnode) //删除一个指定的结点,返回该结点的指针{
CNode *p1,*p2;
p1=pHead; //指向首结点
while(p1!=pnode&&p1->pNext!=0) //寻找要删除的结点
{
p2=p1;
p1=p1->pNext; //结点p2始终在p1的后面
}
if (p1==pHead) //如果要删除的是首结点
{
pHead=pHead->pNext; //将首结点后移
return pnode;
}
p2->pNext=p1->pNext; //p1指向被删除的结点,将p2结点与p1后面的结点连接起来return pnode;
}
CNode *CList::Search(CData &data) //查找一个指定的数据,返回指针,若未找到返回0 {
CNode *p1=pHead;
while(p1) //从头结点开始查找
{
if (p1->pData->Compare(data)==0)
return p1; //找到后返回结点指针
p1=p1->pNext;
}
return 0; //搜索完找不到,返回空指针0
}
void CList::ShowList() //打印整个链表
{
CNode *p1=pHead;
while(p1)
{
p1->pData->Show();
p1=p1->pNext;
}
}
void CList::DeleteList() //删除整个链表结点
{
CNode *p1,*p2;
p1=pHead;
while(p1)
{
delete p1->pData;
p2=p1;
p1=p1->pNext;
delete p2;
}
}
class Repository:public CData //库存为记录,为数据基类的公有派生类{
private :
char szName[20]; //库存中数据:商品名、商品数量和入库时间
unsigned int szNumber;
char szTime[20];
char szN;
CList ShList;
public:
Repository(); //构造函数
Repository(char *name,int number,char *time);
void SetRecord(char *name, int number,char *time); //输入数据函数
int Compare(CData &); //比较函数,比较商品名
void Show();
void AddRecord();
void Display();
void LookUpRecord();
void DeleteRecord();
void ModifyRecord();
void SaveToFile();
void Operate(string &strChoice);
void ReadFromFile();
void Output();
};
Repository::Repository()
{
strcpy(szName,"\0");
szNumber=0;
strcpy(szTime,"\0");
}
Repository::Repository(char *name,int number,char *time)
{
strcpy(szName,name);
szNumber=number;
strcpy(szTime,time);
szN=name[0];
}
void Repository::SetRecord(char *name, int number,char *time) //输入数据函数{
strcpy(szName,name);
szNumber=number;
strcpy(szTime,time);
szN=name[0];
}
int Repository::Compare(CData &data) //比较商品名
{
Repository &temp=(Repository &)data;
return strcmp(szName,temp.szName);
}
void Repository::Show() //打印一个结点的数据
{
cout< void Repository::AddRecord() //将记录添加到链表中 { CNode *pNode; Repository *pSh; char szName[20],szTime[20]; unsigned int szNumber; cout<<"请输入新商品名(输入0退出,并进入系统菜单):"; cin>>szName; while(strcmp(szName,"0")) { cout<<"请输入新商品入库时间: "; cin>>szTime; cout<<"请输入新商品数量: "; cin>>szNumber; pSh=new Repository; //生成新的数据累对象 pSh->SetRecord(szName,szNumber,szTime); //数据类对象赋值 pNode=new CNode; //生成新的结点 pNode->InputData(pSh); //结点插入链表 ShList.AddNode(pNode); count++; cout<<"请输入新商品名(输入0退出,并进入系统菜单) "; cin>>szName; } cout< } void Repository::Display() //显示全部链表数据 { cout<<"当前操作共有"< cout<<"目前库存共有商品信息记录是:\n\n"; cout< ShList.ShowList(); cout< system("pause"); system("cls"); } void Repository::LookUpRecord() // 按照商品名查找 { CNode *pLook; char szName[20]; cout<<"请输入您需要查找的商品名(输入0退出,并进入系统菜单):"; cin>>szName; while (strcmp(szName,"0")) { Repository sh(szName,0,"0"); //生成结点 pLook=ShList.Search(sh); //查找指定结点的数据 if (pLook) { cout<<"在库存商品信息记录中找到商品:"< cout< pLook->ShowNode(); } else cout<<"在库存商品信息记录中找不到商品:"< cout<<"请输入您需要查找的商品名(输入0退出,并进入系统菜单):"; cin>>szName; } cout< } void Repository::DeleteRecord() //在链表中删除指定的结点的数据 { CNode *pLook; char szName[20]; cout<<"请输入您需要删除的商品名(输入0退出,并进入系统菜单):"; cin>>szName; while(strcmp(szName,"0")) { Repository sh(szName,0,"0"); pLook=ShList.Search(sh); if (pLook) //删除时应先查找出结点 { cout<<"在库存商品信息记录中找到商品:"< cout< pLook->ShowNode(); cout<<"请确定是否删除此商品信息记录(Y/N)【确定删除请输入Y或y,取消删除请输入N 或n】:"; char ok; cin>>ok; if (ok=='Y'||ok=='y') { ShList.DeleteNode(pLook); cout< delete pLook; count--; } else if(ok=='N'||ok=='n') cout< } else cout<<"在库存商品信息记录中找不到商品:"< cout<<"请输入您需要删除的商品名(输入0退出,并进入系统菜单):"; cin>>szName; } cout< } void Repository::ModifyRecord() //修改商品记录 { CNode *pLook; Repository *pSh; char szName[20],szTime[20]; unsigned int szNumber; cout<<"请输入您需要修改的商品名(输入0退出,并进入系统菜单):"; cin>>szName; while(strcmp(szName,"0")) { Repository sh(szName,0,"0"); pLook=ShList.Search(sh); if (pLook) //修改时应先查找出结点 { cout<<"在库存商品信息记录中找到商品:"< cout< pLook->ShowNode(); cout<<"-----下面开始修改-----"< cin>>szName; cout<<"请输入修改后的商品数量:"; cin>>szNumber; cout<<"请输入修改后的商品入库时间: "; cin>>szTime; cout<<"请确定是否修改此记录(Yes (Y) or No(N)):"; char ok; cin>>ok; if (ok=='Y'||ok=='y') { pSh=new Repository; pSh->SetRecord(szName,szNumber,szTime); pLook->InputData(pSh); cout< } else if(ok=='N'||ok=='n') cout< } else cout<<" 在库存商品信息记录中找不到"< cout<<" 请输入您需要修改的商品名(输入0退出,并进入系统菜单):"; cin>>szName; } } void Repository::Output() { CNode *pLook; Repository *pSh; char szName[20]; unsigned int szNumber; cout<<"请输入您需要出库的商品名(输入0退出,并进入系统菜单):"; cin>>szName; while(strcmp(szName,"0")) { Repository sh(szName,0,"0"); pLook=ShList.Search(sh); if (pLook) //修改时应先查找出结点 { pSh=(Repository *)pLook->GetData(); cout<<"在库存商品信息记录中找到商品:"< cout< pLook->ShowNode(); if (0==pSh->szNumber) { cout<<"该商品缺货,请及时补充!"< } else { cout<<"请输入您要取出的商品数量:"; cin>>szNumber; cout<<"请确定是否取出该商品( Yes (Y) or No(N) ):"; char ok; cin>>ok; if(ok=='Y'||ok=='y') { if(pSh->szNumber<=szNumber) { cout< pSh->szNumber=0; } else { pSh->szNumber-=szNumber; cout< } cout< } else if(ok=='N'||ok=='n') cout< } } else cout<<" 在库存商品信息记录中找不到"< cout<<" 请输入您需要出库的商品名(输入0退出,并进入系统菜单):"; cin>>szName; } } void Repository::SaveToFile() //将链表中的数据保存在文件中 { ofstream outfile("repository.dat",ios::binary); if(! outfile) { cout<<"数据文件打开错误,没有将数据存入文件!\n"; return; } CNode *pnode; Repository *pSh; string strName,strNumber; pnode=ShList.GetListHead(); //取出链表首结点指针 while(pnode) { pSh=(Repository *)pnode->GetData(); //返回结点指向的数据域指针 outfile.write((char *)pSh,sizeof(Repository)); //将数据域写入文件 pnode=ShList.GetListNextNode(pnode); // 取下一结点的指针} outfile.close(); } void Repository::ReadFromFile() //在程序开始先查找有无数据文件,找到后读取文件数据{ ifstream infile("repository.dat",ios::binary); if(! infile) { cout<<"没有数据文件,请您先添加!\n\n"; return; } CNode *pNode; Repository *pSh; while(! infile.eof()) { pSh=new Repository; //定义数据域对象 infile.read((char *)pSh,sizeof(Repository)); pNode=new CNode; pNode->InputData(pSh); //数据域对象内容生成结点 ShList.AddNode(pNode); //将结点加入链表 } ShList.DeleteNode(pNode); //由于文件多读一次,所以将首结点删除 infile.close(); } void Repository::Operate(string &strChoice) //根据主菜单选项进行操作 { if (strChoice=="1") AddRecord(); else if (strChoice=="2") Display(); else if (strChoice=="3") LookUpRecord(); else if (strChoice=="4") DeleteRecord(); else if(strChoice=="5") ModifyRecord(); else if(strChoice=="6") Output(); else if (strChoice=="0") SaveToFile(); else cout<<"对不起,您的输入有误,请重新输入您的选择: "; } void main() { Repository repository; cout<<"*******************************************************************\n\n"; cout<<" 欢迎进入库存管理系统\n\n"; cout<<"*******************************************************************\n\n"; repository.ReadFromFile(); //从文件中输入数据 string strChoice; //接受主菜单选项 do { cout<<"【欢迎进入系统菜单】:\n\n\n"; cout<<" <1>.添加新商品信息记录\n\n"; cout<<" <2>.显示库存中商品信息记录内容\n\n"; cout<<" <3>.根据商品名查询库存中商品信息记录\n\n"; cout<<" <4>.根据商品名删除库存中商品信息记录\n\n"; cout<<" <5>.根据商品名修改库存中商品信息记录\n\n"; cout<<" <6>.商品出库\n\n"; cout<<" <0>.退出系统\n\n\n"; cout<<"【请输入您的选择】:"; cin>>strChoice; system("cls"); repository.Operate(strChoice); }while(strChoice!="0"); cout<<"***********************************************************************\n\n"; cout<<" ------------******欢迎再次使用库存管理系统******---------- \n\n"; cout<<"***********************************************************************\n\n"; system("pause"); }