You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
biubiubiuBui ae791921a3 Initial commit 2 years ago
src Initial commit 2 years ago
LICENSE Initial commit 2 years ago
README.md Initial commit 2 years ago

README.md

基于C语言实现的超市管理系统

1 需求分析

超市随着市场经济和现代信息技术的的发展,不可必要的要卷入信息现代化的大潮,如何使用现代化的工具,使企业和经营者个人在最小的投入下获取最大的回报,成为每一个人的梦想。因此,在超市管理中引进现代化的办公软件,就成为时下最好的解决办法。使用软件办公,不仅能使经营者的劳力资本减少,同时能使超市的管理更规范更合理,解决了超市中用于管理进出货以及购买、库存等众多繁琐、工作量巨大从而导致耗费人员过多,超市经营紊乱等众多问题。

1.1 主要功能

  • 超级管理员模块:(需帐号登录)

    • 添加管理员
    • 删除管理员
  • 管理员模块:(需帐号登录)

    • 商品信息录入(编号、名称、单价、库存)
    • 商品信息修改(修改商品的各种信息)
    • 商品信息查询(根据所输入的商品名字,编码查询库存信息)
    • 商品信息删除(从商品文件中删除商品信息)
    • 商品信息排序(按编号,单价,库存3种模式进行排序)
    • 输出商品全部库存信息
    • 删除普通用户功能(管理员有权限删除普通用户帐号)
  • 普通用户模块:(需帐号登录)

    • 新用户注册
    • 用户登录:
      • 商品查询
      • 商品排序
      • 输出商品全部库存信息
      • 购买商品(通过用户余额来进行购买)
      • 充值(通过输入充值卡卡号对用户余额充值)
      • 修改用户密码

1.2 运行环境

  • 操作系统:Windows NT/2000/XP/VISTA/WIN7/WIN8/WIN10

  • 开发平台:Microsoft Visual Studio 2012

1.3 文件说明

  • 程序源代码(超市管理系统.cpp)

  • 程序运行文件(超市管理系统.exe)

  • 管理员信息(管理员信息.txt)

  • 普通用户信息(普通用户信息.txt)

  • 商品信息(商品信息.txt)

2 总体方案设计

2.1 设计方案

整个超市管理系统分为3个模块,超级管理员+管理员+普通用户,其中:

  • 管理员可以实现商品信息的录入,修改,查询等管理操作,同时还拥有对普通用户帐号的管理

  • 超级管理员是最高执行者,拥有对管理员帐号的操作权限,可以对管理员帐号进行添加或删除

  • 普通用户模块,由于考虑到该程序的真实性,所以实现了普通用户的注册和登录功能,用户要进行购物,必须使用帐号(可自行注册,无须经过管理员),其中普通用户具有商品查询等一部分功能。特色功能是具有帐号余额功能,同时购物可以进行充值功能(输入充值卡卡号,类似于购买充值卡来充值)

2.2 主要结构

  • 超级管理员模块:(需帐号登录)

    • 添加管理员
    • 删除管理员
  • 管理员模块:(需帐号登录)

    • 商品信息录入(编号、名称、单价、库存)
    • 商品信息修改(修改商品的各种信息)
    • 商品信息查询(根据所输入的商品名字,编码查询库存信息)
    • 商品信息删除(从商品文件中删除商品信息)
    • 商品信息排序(按编号,单价,库存3种模式进行排序)
    • 输出商品全部库存信息
    • 删除普通用户功能(管理员有权限删除普通用户帐号)
  • 普通用户模块:(需帐号登录)

    • 新用户注册
    • 用户登录:
      • 商品查询
      • 商品排序
      • 输出商品全部库存信息
      • 购买商品(通过用户余额来进行购买)
      • 充值(通过输入充值卡卡号对用户余额充值)
      • 修改用户密码

2.3 程序功能和流程图

由于本程序模块功能较多,有超级管理员,管理员和普通用户,共3个模式的功能,流程图较大,因此分为3个子图。

**超级管理员模块 **

**管理员模块 **

**普通用户模块 **

2.4 数据结构和算法的设计说明

本程序有3个数据结构:管理员,普通用户,商品共3个结构体。其中程序拥有超级管理员、管理员和普通用户共3种身份,运用链表来存储和读取所保存的信息。

2.4.1 结构体类型

一开始选择模块,输入帐号和密码,进行验证,是否正确。正确就进入功能模块。

typedef struct custom* cpointer;//结点指针类型
struct custom{
	string custom_ID;//帐号
	string custom_name;//姓名
	string custom_mima;//密码
	double money;//账户余额
	cpointer next;
};
typedef cpointer clklist;//单链表类型,即头指针类型

其中,管理员、普通用户、商品都是定义结构体,而后进入系统,一开始便定义相对应的链表进行存储和获取已保存的信息。

2.4.2 算法设计

排序算法

    for(int i=0;i<Goodnum;i++){
		for(int j=Goodnum;j>=i+1;j--){
			if(Go.Good[j].Good_ID<Go.Good[j-1].Good_ID)
             {//比较编号大小,小的在前面,大的在后面
				flag=1;
				p=Go.Good[j];
				Go.Good[j]=Go.Good[j-1];
				Go.Good[j-1]=p;
             }
        }

通过对相邻2个商品的编号不断比较,排序,运用2个for循环,比较编号大小,小的在前面,大的在后面。不断变换,最终排序完成。

2.5 程序关键源代码说明

程序中拥有3个身份:超级管理员,管理员,普通用户。不同身份之间函数都差不多,因此将函数直接展示,不说明为哪个身份的权限功能。

custom_ender函数:登录验证函数。对输入的帐号和密码进行验证检索,正确就进入对应的身份模块。先定义一个普通用户结构体类型cpointer对象p,把包含普通用户全部信息的单链表head赋值给p,而后对p进行检索,如果p链表中的用户信息与输入的用户信息(帐号+密码)相同,就返回1;不同就显示“用户帐号不存在”,同时返回0。

int custom_ender(clklist &head,string ID,string mima){
	cpointer p;
	p=head;
	while(p!=NULL) {
		if(p->custom_ID==ID&&p->custom_mima==mima) return 1;
		else p=p->next;
	}
	cout<<"用户帐号不存在!"<<endl;
	return 0;
} 

custom_creat函数:注册函数。先定义一个普通用户结构体类型cpointer对象p,把包含普通用户全部信息的单链表head赋值给p,而后输入注册用户的各种信息(帐号,密码,姓名),如果输入的帐号ID与已保存的用户帐号相同,就显示已存在,提示重新输入。最后将输入的新注册用户信息运用头插法插入,保存到”普通用户信息.txt”文件中保存

void custom_creat(clklist &head){
	cpointer s,p;
	string ID,name,mima;
	int sign=1,flat=1;
	while(sign!=0){
		flat=1;
		cout<<"请输入用户帐号"<<endl;
		cin>>ID;
		p=head->next;
		while(p!=NULL){
			if(p->custom_ID==ID) flat=0;
			p=p->next;
		}
		if(flat==0) {
			cout<<"用户帐号已存在,请重新输入"<<endl;
			continue;
		}
		cout<<"请输入用户密码"<<endl;
		cin>>mima;
		cout<<"请输入用户姓名"<<endl;
		cin>>name;
		s=new custom;
		s->custom_ID=ID;
		s->custom_name=name;
		s->custom_mima=mima;
		s->money=0;
		s->next=head->next;//使用头插法建表
		head->next=s;
		buyernum++;//输入一个用户信息,buyernum自加1
		custom_save(head);
		cout<<"是否继续注册?<继续>请按1  <结束>请按0"<<endl;
		cin>>sign;//while循环判断条件,所以不需要用if
	}
} 

custom_get函数:从文件获取用户信息函数。先定义一个普通用户结构体类型cpointer对象p,把包含普通用户全部信息的单链表head赋值给p, 而后运用一个for循环,将用户信息从“普通用户信息.txt“全部导入到p链表中,返回给系统。

clklist custom_get(clklist &buyer){
	cpointer s,p;//s用于存储用户信息,p用于buyer的连接
	string numname;
	string ID,name,mima;
	double money;
	buyer->next=NULL;
	p=buyer;
	ifstream ifile("C:\\普通用户信息.txt",ios::in);
	if(!ifile){
		cerr<<"用户信息查询出错"<<endl;return 0;
	}
	ifile>>numname;
	ifile>>buyernum;//从文件中提取用户个数,用于for循环
	for(int i=1;i<=buyernum;i++){
		ifile>>ID;
		ifile>>name;
		ifile>>mima;
		ifile>>money;
		s=new custom;
		s->custom_ID=ID;
		s->custom_name=name;
		s->custom_mima=mima;
		s->money=money;
		s->next=p->next;
		p->next=s;
	}
	buyer=p;
	ifile.close();
	return buyer;
}

Good_add函数:商品信息录入函数。把包含商品信息的链表Goods传入该函数,输入商品编号,if(Good_ender1(Goods,ID)==0)进行检索是否商品已存在,存在就提示重新输入,不存在就继续录入商品信息,导入到Goods链表中,最后运用Good_save(Goods)保存全部信息到“商品信息.txt”文件中。

void Good_add(sqlist &Goods){
	string ID,name;
	double piece;
	int last,sign,flat=1;//last为商品库存,sign用于判断选择
	fstream ifile("C:\\商品信息.txt",ios::in);
	for(;flat!=0;) {
		cout<<"请输入商品编号:";
		cin>>ID;
		if(Good_ender1(Goods,ID)==0) {
			cout<<"请输入商品名称:";
			cin>>name;
			if(Good_ender2(Goods,name)==0) {
				cout<<"请输入商品单价:";
				cin>>piece;
				cout<<"请输入商品数量:";
				cin>>last;
				Goods.Good[Goodnum].Good_ID=ID;
				Goods.Good[Goodnum].Good_name=name;
				Goods.Good[Goodnum].piece=piece;
				Goods.Good[Goodnum].last=last;
				Goodnum++;//添加完信息就自加1
				Good_save(Goods);//添加完就保存至商品信息.txt
				cout<<"是否继续录入?<继续>请按1  <结束>请按0"<<endl;
				cin>>sign;
				if(sign==0) break;
			}
			else {cout<<"商品名称已存在!<重新输入>请按1  <结束>请按0"<<endl;
			cin>>flat;}
		}
		else {cout<<"商品编号已存在!<重新输入>请按1  <结束>请按0"<<endl;
		cin>>flat;}
	}
}

Good_change函数:商品信息修改函数。把包含商品信息的链表Goods传入该函数,考虑到用户可能只记得商品编号或者商品名称,因此编写了2种修改模式(按编号检索修改,还是按名称检索修改)。如果选择按编号检索修改,同样对编号进行检索,如果在Goods链表中找到该商品编号,就运用 sign=Good_locate1(Goods,ID);定位记录下该商品在文件中的位置,而后输入修改后的商品信息,保存至文件中;按名称检索修改类似。最后修改完后,会提示是否继续修改,如果不继续就返回用户功能界面,执行其他功能。

void Good_change(sqlist &Goods){
	string ID,name;
	int sign;//sign用于定位要修改商品的位置
	int a,flat=1;//a用于switch
	for(;flat!=0;){
	cout<<"<输入要修改的商品编号>请按1   <输入要修改的商品名称>请按2"<<endl;
	cin>>a;
	if(a!=1&&a!=2) {cout<<"选择有误,请重新输入"<<endl;continue;}
	switch(a){
	case 1:
		{
		cout<<"请输入商品编号:";
		cin>>ID;
		if(Good_ender1(Goods,ID)==1) {
			sign=Good_locate1(Goods,ID);
			cout<<"商品编号:"<<Goods.Good[sign].Good_ID<<endl;
			cout<<"商品名称:"<<Goods.Good[sign].Good_name<<endl;
			cout<<"商品单价:"<<Goods.Good[sign].piece<<endl;
			cout<<"商品库存:"<<Goods.Good[sign].last<<endl;
			cout<<"请输入修改后的信息:"<<endl;
			cout<<"商品编号:";
			cin>>Goods.Good[sign].Good_ID;
			cout<<"商品名称:";
			cin>>Goods.Good[sign].Good_name;
			cout<<"商品单价:";
			cin>>Goods.Good[sign].piece;
			cout<<"商品库存:";
			cin>>Goods.Good[sign].last;
			Good_save(Goods);//保存信息
			cout<<"修改成功"<<endl;
		}
		else cout<<"商品不存在!"<<endl;
		break;
		}
	case 2:  大致与编号模式相同
		else cout<<"商品不存在!"<<endl;
		break;
		}
	}//switch的
	cout<<"<继续修改>请按1  <退出>请按0"<<endl;
	cin>>flat;
	}//for循环的
}

Good_inquire函数:商品信息查询函数。把包含商品信息的链表Goods传入该函数,考虑到用户可能只记得商品编号或者商品名称,因此编写了2种查询方式(按编号检索查询,还是按名称检索查询)。如果选择按编号检索查询,同样对编号进行检索,如果在Goods链表中找到该商品编号,就运用 sign=Good_locate1(Goods,ID);定位记录下该商品在文件中的位置,而后输出该商品信息的全部信息;按名称检索查询类似。最后查询完后,会提示是否继续查询,如果不继续就返回用户功能界面,执行其他功能。

void Good_inquire(sqlist &Goods){
	string ID,name;
	int a,sign,flat=1;
	for(;flat!=0;){
	cout<<"<按商品编号查询>请按1   <按商品名称查询>请按2"<<endl;
	cin>>a;
	if(a!=1&&a!=2) {cout<<"选择有误,请重新输入"<<endl;continue;}
	switch(a){
	case 1:
		{
			cout<<"请输入商品编号:";
			cin>>ID;
			if(Good_ender1(Goods,ID)==1) {
			sign=Good_locate1(Goods,ID);
			cout<<"商品编号:"<<Goods.Good[sign].Good_ID<<endl;
			cout<<"商品名称:"<<Goods.Good[sign].Good_name<<endl;
			cout<<"商品单价:"<<Goods.Good[sign].piece<<endl;
			cout<<"商品库存:"<<Goods.Good[sign].last<<endl;
			}
			else cout<<"商品不存在!"<<endl;
			break;
		}
	case 2: 大致与编号模式相同
			else cout<<"商品不存在!"<<endl;
			break;
		}
	}//switch的
	cout<<"是否继续查询?<继续>请按1  <结束>请按0"<<endl;
	cin>>flat;
	if(flat==0) break;
	}//for循环的
}

Good_delete函数:商品信息删除函数。把包含商品信息的链表Goods传入该函数,考虑到用户可能只记得商品编号或者商品名称,因此编写了2种删除方式(按编号检索删除,还是按名称检索删除)。如果选择按编号检索删除,同样对编号进行检索,如果在Goods链表中找到该商品编号,就运用 sign=Good_locate1(Goods,ID);定位记录下该商品在文件中的位置,而后使用for(int i=sign; i<Goodnum; i++)将该位置后的商品全部前移1位,覆盖掉该位置,最后保存删除后的商品信息至“商品信息.txt”中;按名称检索删除类似。最后删除完后,会提示是否继续删除,如果不继续就返回用户功能界面,执行其他功能。

void Good_delete(sqlist &Goods){
	int a,sign,flat=1;
	string ID,name;
	for(;flat!=0;){
	cout<<"<输入要删除的商品编号>请按1   <输入要删除的商品名称>请按2"<<endl;
	cin>>a;
	if(a!=1&&a!=2) {cout<<"选择有误,请重新输入"<<endl;continue;}
	switch(a){
	case 1:
		{
			cout<<"请输入要删除的商品编号:";
			cin>>ID;
			if(Good_ender1(Goods,ID)==1){
			sign=Good_locate1(Goods,ID);
			for(int i=sign;i<Goodnum;i++){
				Goods.Good[i]=Goods.Good[i+1];
			}
			Goodnum--;
			Good_save(Goods);
			cout<<"删除成功!"<<endl;
			}
			else cout<<"商品不存在!"<<endl;
			break;
		}
	case 2: 大致与编号模式相同
			else cout<<"商品不存在!"<<endl;
			break;
		}
	}//switch的
	cout<<"是否继续删除?<继续>请按1  <结束>请按0"<<endl;
	cin>>sign;
	if(sign==0) break;
	}//for循环的
}

Good_range函数:商品信息排序函数。把包含商品信息的链表Go传入该函数,选择排序模式(按编号,单价,库存进行排序),运用2层for循环,使用冒泡法进行排序,从尾部向头部进行对比检索,小的放前面,大的放后面,排序完之后就将排序后的商品信息显示给用户;3种模式大致相同。最后排序完后,会提示是否继续执行,如果不继续就返回用户功能界面,执行其他功能。

void Good_range(sqlist Go){
	Goods p;
	p.piece=0;
	p.last=0;
	int a,flag=0,flat=1;
	for(;flat!=0;){
	cout<<"<按商品编号排序>请按1  <按商品单价排序>请按2  <按库存数量排序>请按3  <退出>请按0"<<endl;
	cin>>a;
	if(a!=0&&a!=1&&a!=2&&a!=3) {cout<<"选择有误,请重新输入"<<endl;continue;}
	switch(a){
	case 1:
		{
			for(int i=0;i<Goodnum;i++){
				for(int j=Goodnum;j>=i+1;j--){
					if(Go.Good[j].Good_ID<Go.Good[j-1].Good_ID){//比较编号大小,小的在前面,大的在后面
						flag=1;
						p=Go.Good[j];
						Go.Good[j]=Go.Good[j-1];
						Go.Good[j-1]=p;
					}
				}//jfor的
				if(!flag) break;
			}//ifor的
			cout<<"商品编号"<<setw(10)<<"商品名称"<<setw(10)<<"商品单价"<<setw(10)<<"商品库存"<<endl;
			for(int i=1;i<=Goodnum;i++){
				cout<<Go.Good[i].Good_ID<<setw(13)<<Go.Good[i].Good_name<<setw(8)<<Go.Good[i].piece<<setw(10)<<Go.Good[i].last<<endl;			
			}
			break;
		}
	case 2: 大致与编号模式相同
	case 3: 大致与编号模式相同
	case 0:return;
    }//switch的
    }//最外层for的

Good_buy函数:购买商品函数。把包含商品信息的链表Goods以及包含用户信息的链表head传入该函数,选择购买模式(输入编号或名称进行购买),如果输入的商品编号与Goods中的商品信息相同,就提示购买数量,这时如果购买数量超过库存数量会提示“库存不足”,然后重新输入;如果购买商品所支付的钱超过用户的余额,则提示“余额不足”,是否前往充值页面进行充值。充值模块下面会展示。购买完商品后,用户可以继续购买,也可以返回用户功能界面。

void Good_buy(sqlist &Goods,clklist &head,string cID){//cID为用户帐号
	string ID,name;
	int a,shu,sign,flat=1;
	cpointer p;
	p=custom_locate(head,cID);
	for(;flat!=0;){
	cout<<"<输入商品编号购买>请按1   <输入商品名称购买>请按2"<<endl;
	cin>>a;
	if(a!=1&&a!=2) {cout<<"输入有误,请重新输入"<<endl;continue;}
	switch (a)
	{
	case 1:
		{
			cout<<"请输入商品编号:";
			cin>>ID;
			if(Good_ender1(Goods,ID)==1)
			{
				sign=Good_locate1(Goods,ID);
				cout<<"请输入购买数量:";
				cin>>shu;
				if(shu<=Goods.Good[sign].last){
					if(p->money<Goods.Good[sign].piece*shu) 
					{cout<<"余额不足,请充值!"<<endl;
					cout<<"是否前往充值?<充值>请按1  <否>请按0"<<endl;
					cin>>flat;
					if(flat==0) break;
					if(flat==1) return;}
					Goods.Good[sign].last=Goods.Good[sign].last-shu;
					cout<<"购买成功"<<endl;
					p->money=p->money-Goods.Good[sign].piece*shu;//账户余额减少,扣费成功
					custom_save(head);
					cout<<"账户余额:"<<p->money<<endl;
					Good_save(Goods);
				}
				else cout<<"库存不足!"<<endl;
			}
			else cout<<"找不到相应商品,购买失败"<<endl;
			break;
		}
	case 2:与编号模式类似
	}//switch的
	cout<<"是否继续购物?<继续>请按1  <结束>请按0"<<endl;
	cin>>flat;
	if(flat==0) break;
	}//for的
}

custom_addmoney函数:余额充值函数。余额是用户帐号中的一个成员,初始为0,用户在购物的时候余额会减少,如果余额不足就无法进行购物,需要进行充值,充值是输入系统给定的充值卡卡号进行充值,这是本系统的一大亮点。把包含用户信息的链表head传入该函数,运用 p=custom_locate(head,ID);定位是哪个用户的帐号要进行充值,其中,系统设定了2种充值卡“asd500”和“asd1000”分别可以充值500和1000元,这类似与用户购买不同的充值卡给自己的账户进行充值。用户输入充值卡卡号,进行检索是否与系统设定的充值卡卡号相同,如果相同就充值相应的金额;如果不同,就提示“充值卡无效”。最后充值后,用户可以选择继续充值或者返回用户功能界面进行购物等其他操作。

void custom_addmoney(clklist &head,string ID){
	cpointer p;
	int sign=1;
	p=custom_locate(head,ID);
	string acard,card1="asd500",card2="asd1000";
	while(sign!=0){
	cout<<"请输入您获得的充值卡卡号:";
	cin>>acard;//acard是用户获得的充值卡
	if(acard!=card1&&acard!=card2) cout<<"充值卡无效"<<endl;
	if(acard==card1)
	{
		p->money+=500;
		cout<<"充值成功!"<<endl;
		cout<<"账户余额:"<<p->money<<endl;

	};
	if(acard==card2)
	{
		p->money+=1000;
		cout<<"充值成功!"<<endl;
		cout<<"账户余额:"<<p->money<<endl;

	};	
	custom_save(head);//充值成功
	cout<<"是否继续充值?<继续>请按1  <结束>请按0"<<endl;
		cin>>sign;//while循环判断条件,所以不需要用if
	}

3 程序功能测试

一开始进入系统,初次使用会提示文件打开失败,是正常的,不影响功能。由于原本的“管理员信息.txt”“普通用户信息.txt”“商品信息.txt”是空的,当录入信息就不会有提示了。进入身份选择(都要帐号和密码)

选择1进入超级管理员,(帐号:asd,密码123),先添加管理员。

选择1,添加管理员信息(帐号+密码+姓名),添加完后可以选择继续添加或返回

选择2,输入要删除的管理员帐号,直接删除管理员

添加完管理员后,可返回主菜单,进入管理员模式,输入刚刚添加的管理员帐号+密码,进入管理员模式

功能1,进入商品录入功能,输入商品的信息(编号,名称,单价,库存),当录入成功之后,管理员可以选择继续录入或返回(该模块当录入编号和名称和已录入的信息相同会提示出错,重新录入)

功能2,可进行商品修改,有2种模式进行选择,输入商品编号101后,显示“商品信息.txt“文件中的商品信息,而后管理员可以输入修改后的信息

功能3,可以进行商品信息查询,可以查询到刚刚修改的联想笔记本

功能4,可以进行删除已录入的商品信息,例如,删除刚录入的联想笔记本

删除后,进入查询功能查看联想笔记本,不存在,表明删除成功~ ~

功能5,进行已录入商品信息排序,可选择(编号,单价,库存)进行从小到大排序,编号也是可以的

功能6,输出全部商品信息

功能7,删除普通用户,如果已经有普通用户,只需要输入普通用户的帐号就可以直接删除

进入普通用户模块,如果没有帐号是无法查看和购物的,因此消费者可以自行注册

注册完,就可以登录进入用户模块进行购物了

其中,商品查询,排序,库存是和管理员一样的,就不展示了

功能4,购买商品,一开始,由于没充值时,用户余额为0,余额不足,无法购买,用户可以返回,进行充值后购买。如果充值后,余额充足就可以购买了,购买后,余额相应减少

这里我先前往充值2000元,后购买如下,主机单价50,购买后余额为1950,扣费成功

功能5,用户可以随时修改自己的账户密码,保护自己的财产

功能6,就是充值了,输入系统给定的充值卡卡号,有(asd500和asd1000)

由于刚余额1950,现在输入卡号asd1000,成功充值1000,剩余2950

4 总结

这次选择了做“超市管理系统”,在完成基本功能之后,觉得要真正实现成功的超市管理系统,必须要有个人的帐号,因此增加了普通用户注册和帐号模式,同时管理员和超级管理员也都是用帐号+密码进入。普通用户可以自行注册,拥有自己的私人帐号。同时,超市管理系统普通用户在进行购买之后,应该是要有余额的,因此添加了余额成员。拥有余额成员之后,就想到,用户需要购买东西,余额不足就需要进行充值,为了实现真实性,就选定,用户需要输入充值卡卡号进行充值。最终完美实现。

这个系统,是使用链表实现的,由于之前的大作业是使用文件流,不是使用链表,因此这次的大作业就决定说要使用链表来实现。在编程过程中,也发现了很多的bug,最终还是一一解决。感觉自己的编程能力在不断的提高,无论是什么bug都可以自行调试解决。

同时,在思考程序的框架功能时,也逐渐重视用户体验,人机交互。编写大作业,不再只是仅仅满足基本功能,在基本功能上,还添加其余用户体验好的功能(比如帐号登录,充值等等功能),感觉大作业让我学会了很多。

新建文件(夹)
上传文件(夹)
基于C语言实现的超市管理系统