这篇博客是我软件开发与创新课的第一次作业
1)
本文中超市进销存管理系统源码来自室友在大二上c++课程的大作业,故而本文分析和改进所运用的编程语言为C++。
由于本人仍为一名学生,在编程能力上仍有欠缺故在代码的原有基础上进行修改。
2)原超市进销存管理系统代码分析
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
#include<iostream> #include<fstream> #include<ctype.h> #include<stdlib.h> #include<string.h> #include<windows.h> using namespace std; int n=0; //全局数据,结点数量 class Goods { protected: char name[20]; //商品名称 double num; //商品代码 char person[30]; //商品产地 int price; //进货价 double amount; //库存量 Goods *next; public: Goods(double num,char*name,char*person,int price,double amount) { this->num=num; strcpy(this->name,name); strcpy(this->person,person); this->price=price; this->amount=amount; } void Output() { cout<<" num:"<<num<<"\t"; cout<<" name:"<<name<<"\n"; cout<<" person:"<<person<<"\t"; cout<<" price:"<<price<<"\n"; cout<<" amount:"<<amount<<endl; } friend class Supermarket; }; class Supermarket { private: Goods *goods; //商品表 void Clear(); //清除内存中数据 public: Supermarket() { goods=NULL; Load(); } ~Supermarket() { Goods *p; p=goods; while(p) { p=p->next; delete goods; goods=p; } goods=NULL; } void Add(); //增加商品 void Delete(); //删除商品 void Modify(); //修改商品 void Save(); //基础数据存盘 void Load(); //基础数据装入 }; void Supermarket::Clear() //清除内存中商品数据(内部使用) { Goods* p; p=goods; while(p) { goods=p->next; delete p; p=goods; } } void Supermarket::Add() { Goods *p; double num,amount; char name[20],person[30]; int price; cout<<"************************************"; cout<<"\n新增商品信息:\n"; cout<<" 商品代码:"; cin>>num; cout<<" 商品名称:"; cin>>name; cout<<" 商品产地:"; cin>>person; cout<<" 商品单价:"; cin>>price; cout<<" 商品库存量:"; cin>>amount; //创建新商品类结点 p=new Goods(num,name,person,price,amount); p->next=NULL; if(goods==NULL) { goods=p; n++; } else { Goods *p2=goods; while(p2->next) p2=p2->next; p2->next=p; n++; } cout<<"************************************"; } void Supermarket::Delete() //删除商品 { char name[20]; cout<<"************************************"; cout<<"\n 请输入要删除的商品名称:"; cin>>name;//查找要删除的结点 Goods *p1,*p2; p1=goods; while(p1) { if(strcmp(p1->name,name)==0) break; else { p2=p1; p1=p1->next; } } //删除结点 if(p1!=NULL) //若找到结点,则删除 { if(p1==goods) //若要删除的结点是第一个结点 { goods=p1->next; delete p1; n--; } else //若要删除的结点是后续结点 { p2->next=p1->next; delete p1; n--; } cout<<"\n ----\n ---\n --\n -\n 已删除\n"; cout<<"************************************"; } else //未找到结点 { cout<<"\n ----\n ---\n --\n -\n Sorry,未找到!\n"; cout<<"************************************"; } } void Supermarket::Modify() //修改商品信息 { double num,amount; char name[20],person[30]; int price; cout<<"**************修改商品**************\n"; cout<<" 请输入要查的商品名称:"; cin>>name;//查找要修改的结点 Goods *p1,*p2; p1=goods; while(p1) { if(strcmp(p1->name,name)==0) break; else { p2=p1; p1=p1->next; } }//修改结点 if(p1!=NULL) //若找到结点 { p1->Output(); cout<<"\n请选择要修改的信息(1—商品代码,2—商品名称,3—产地,4—单价,5—该商品库存量,6—修改全部信息):\n"; int a; cin>>a; switch(a) { case 1:cout<<" 请输入新代码:"; cin>>num; strcpy(name,p1->name);strcpy(person,p1->person);price=p1->price;amount=p1->amount; break; case 2:cout<<" 请输入新名称:"; cin>>name; num=p1->num;strcpy(person,p1->person);price=p1->price;amount=p1->amount; break; case 3:cout<<" 请输入新产地:"; cin>>person; num=p1->num;strcpy(name,p1->name);price=p1->price;amount=p1->amount; break; case 4:cout<<" 请输入新单价:"; cin>>price; num=p1->num;strcpy(name,p1->name);strcpy(person,p1->person);amount=p1->amount; break; case 5:cout<<" 请输入新库存数据:"; cin>>amount; num=p1->num;strcpy(name,p1->name);strcpy(person,p1->person);price=p1->price; break; case 6:cout<<" 请输入新信息:\n"; cout<<" 商品代码:"; cin>>num; cout<<" 商品名称:"; cin>>name; cout<<" 商品产地:"; cin>>person; cout<<" 商品单价:"; cin>>price; cout<<" 商品库存量:"; cin>>amount; break; }//创建新商品结点 Goods *p3; p3=new Goods(num,name,person,price,amount); //员工结点替换到链表 p3->next=p1->next; if(p1==goods) //若要替换的结点是第一个结点 goods=p3; else //若要替换的结点是后续结点 p2->next=p3; delete p1; //删除原来的商品结点 cout<<"\n修改成功!\n"; } else //未找到结点 cout<<"Sorry,未找到!\n"; cout<<"************************************"; } void Supermarket::Save() //数据存盘 { cout<<"\n是否保存?[Y/N]"; char a; cin>>a; if(a=='n') { return; } if(a=='y'||a=='Y') { ofstream outfile("base.txt",ios::out|ios::app); if(!outfile) { cerr<<"open error!"; exit(1); } Goods* p; p=goods; while(p) { outfile<<p->num<<" "; outfile<<p->name<<" "; outfile<<p->person<<" "; outfile<<p->price<<" "; outfile<<p->amount<<endl; cout<<endl; p=p->next; } outfile.close(); } } void Supermarket::Load() //数据装入 { Goods *p=goods; ifstream infile("base.txt",ios::in|ios::binary);//读一条信息 if (!infile.good()) { return; } p=new Goods(1,"a","a",1,1); infile>>p->num>>p->name>>p->person>>p->price>>p->amount; while(infile.good()) { //创建商品结点 p=new Goods(p->num,p->name,p->person,p->price,p->amount); p->next=NULL; //商品结点加入 if(goods) //若已存在结点 { p->next=goods; goods = p; //Goods*p2; //p2=goods; //while(p2->next) //查找尾结点 // p2=p2->next; //p2->next=p; //连接 } else //表空 { goods=p; //连接 }//读下一条信息 infile>>p->num>>p->name>>p->person>>p->price>>p->amount; } cout<<"\n商品数据已经装入\n"; } int main() { system("color 71"); int i; char c; Supermarket a; do{ cout<<"\n*********超市进销存管理系统*********\n"; cout<<" * 1—增加商品 *\n"; cout<<" * 2—删除商品 *\n"; cout<<" * 3—修改商品 *\n"; cout<<" * 4—退出 *\n"; cout<<"************************************\n"<<"请选择(1—4): "; cin>>c; switch(c) { case '1': system("cls"); a.Add(); a.Save(); system("cls"); break; case '2': system("cls"); a.Delete(); a.Save(); system("cls"); break; case '3': system("cls"); a.Modify(); a.Save(); system("cls"); break; } }while(c!='4'); return 0; }
在该系统中主要是设置了两个类:goods类和其的友元类Supermarket。goods类主要是以保护类型设置了商品的基础信息和以公有类型设置了构造函数和输出函数。Supermarket类设置友元类的主要原因是该类中主要是以公有类型设置了在公有类中定义的功能函数,这些函数需要运用到goods类中保护类型的数据。
类:
Goods类:
变量:
char name[20]; //商品名称 double num; //商品代码 char person[30]; //商品产地 int price; //进货价 double amount; //库存量 Goods *next;指针变量
函数:
Goods(double num,char*name,char*person,int price,double amount)//构造函数
void Output()//输出函数,主要用于后续函数中的整体输出
Supermarket类:
变量:
Goods *goods; //商品表 void Clear(); //清除内存中数据
函数:
Supermarket()//构造函数
~Supermarket()//析构函数
void Add(); //增加商品
void Delete(); //删除商品
void Modify(); //修改商品
void Save(); //基础数据存盘
void Load(); //基础数据装入
同时该系统对于文件信息的存取调用方面有着与众不同的方式,通常情况下我们学生使用文件的存储与使用仅仅是使用一个函数,而该代码设计了两个函数来实现数据文件的使用与存储有效的区分。文件读取与存储模块主要是两个函数数据装盘和数据装入,数据装盘函数还有一个询问是否保存的功能,用户确认保存之后,就是先创建一个名为“best.txt”的文本文件,将商品信息以特定格式写入文件中。数据装入函数就是在名为“best.txt”的文本文件中事先存在数据的情况下,将其中的数据存入链表中。在阅读该小组源代码的时候发现该组代码中对于链表的使用比较周全,这使得阅读代码和运行代码的效率都有不同的影响。
源代码需求是超市货物的增加修改和删除,对于一个超市货物管理系统来说需求已基本满足,但是,在某些方面仍有较大的改善空间。如商品在系统中的统计数据,缺乏一些看似无需其实比较重要的功能。同时在原码中有设置全局变量来控制节点,但是在代码中它的使用,似乎并没有体现出来。
3)改进
通过利用代码原作者在原码中设置的全局变量节点来进行操作,增设了统计商品的功能。统计商品功能:主要是统计商品的数量和总价。通过查找设置的全局变量结点,再将结点中的数量和单价相乘,最后输出。下面是新增加的代码:
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
void Supermarket::Add_up() //统计超市商品总数量于价值 { cout<<"\n****商品统计****\n"; double Amount=0,Value=0; char name[20]; cout<<"\n请输入要统计的商品名称:\n"; cin>>name; Goods *p1; p1=goods; while(p1) { if(strcmp(p1->name,name)==0) break; else p1=p1->next; } if(p1) { while(p1) { Amount+=p1->amount; Value+=p1->amount*p1->price; p1=p1->next; } cout<<"商品总数量是:\n"; cout<<Amount; cout<<"\n商品总价值是:\n"; cout<<Value; } else cout<<"\nSorry,未找到该类商品!\n"; }
同时在Supermarket类中添加了这个新的函数名
4)运行效果截图