销售管理系统_手机销售信息管理系统 c 语言-程序员宅基地

技术标签: 课设  C  c语言  销售系统  链表  

C语言-------销售管理系统

一.需求分析

A.功能需求
很多商品销售机构都需要用到销售管理系统,商品信息包含的字段很多,比如包括:商品编号、商品名称、商品类别(普通电视机、DVD、带DVD的电视机,带DVD的电视机的售价为普通电视机和DVD单价之和的80%)、商品进货价格、商品销售价格、商品数量、供应商名称等。对系统的具体要求如下:
 销售商品信息增删改查。
 销售商品退货管理。
 销售商品进货价格管理。
 销售商品销售价格管理。
 销售商品统计功能。
 销售商品排序(价格)功能。

B.技术要求:
(1)能够运用C语言知识和结构化编程思想,对实际问题进行分析,设计具有一定创新性的实现方案,并能够对相关方案进行筛选;
(2)必须遵守软件工程的相关职业道德和规范,培养良好的编码规范和习惯。例如变量、函数命名必须做到见名知义,代码必须有必要的注释等;
(3)所有的数据存储必须采用文件的形式,可以采用文本文件或者二进制文件;
(4)工程结构尽量采用多文件结构,且文件结构必须合理;
(5)必须采用标准的C语言输入输出;
(6)能够通过相应的软件测试保证所编写代码的质量。

二. 概要设计

⒈ 设计商品信息的抽象数据类型定义:struct woodinfo{}
⒉ 重要的基本函数模块:
基本操作                           操作结果
struct Node* list = NULL;  创建全局链表
struct Node* createHead()   创建表头
struct Node* createNode()   创建节点:为插入做准备
void printList()                      打印链表函数(仓库数据)
void printListSimple()           打印链表函数(商品数据)
void insertNodeByHead()     链表插入函数Push(&S,e)
struct Node* searchByName   指定位置查找
void deleteNodeByData        指定位置删除
void menu()                           菜单模块
void saveInforFormFile        文件存操作
void readInfoFromFile          文件读操作
void bubbleSortList()            冒泡排序法
void keyDown()                    交互模块
int main()                              主函数
⒊ 商品的抽象数据类型定义:
struct woodinfo
{
int num;//商品编号
char name[20];//商品名称
char type[20];//商品种类(DVD)
float inprice;//进价
float outprice;//售价
int many;//数量
char soldmane[20];//供应商
} ;
基本操作:
void saveInforFormFile--------------------------------文件存操作
初始条件:利用FILE函数在程序运行时自动创建出一个woodinfo(商品信息)的文档(.txt),之后在利用链表依次讲链表中的信息填入文档中,并实行保存。
操作结果:输入完毕后,文件夹中会自动生成一个woodinfo(.txt)文件,并存储着链表内信息。

void readInfoFromFile--------------------------------文件读操作
初始条件:已存储在FILE中的数据待读阅。
操作结果:利用遍历的方式依次输出链表中包含的内容,并打印出来。

void bubbleSortList()--------------------------------冒泡排序法
初始条件:利用冒泡排序法的算法对链表中的每件商品的价格进行排序,并储存在FILE文件内,实行实时更新。
操作结果:商品会因价格的高低排序表示出来。

struct Node* searchByName
操作结果:通过遍历自定义结构体中的商品名字进行查找,并将查找的结果反馈到桌面,如果找到则直接显示出商品的相关信息,为找到则输出“未找到该商品!”。

void deleteNodeByData-------------------------------指定位置删除
操作结果:过遍历自定义结构体中的商品名字进行查找,并将查找的结果从链表中删除并将删除后的信息保存于文档中。

三.详细设计

#include<stdio.h>
#include<stdlib.h>
#include<string.h>
//自定义结构体(商品信息)
struct woodinfo
{
    
	int num;//商品编号 
	char name[20];//商品名称 
	char type[20];//商品种类(DVD)
	float inprice;//进价 
	float outprice;//售价
	int  many;//数量
	char  soldmane[20];//供应商 
 } ; 
 
struct Node
{
    
	struct woodinfo data;
	struct Node* next;
};
struct Node* list = NULL;//创建全局链表 
//创建表头
struct Node* createHead()
{
    
	//动态内存申请
	struct Node* headNode = (struct Node*)malloc(sizeof(struct Node));
	headNode->next = NULL;
	return headNode; 
} 
//创建节点:为插入做准备
struct Node* createNode(struct woodinfo data)
{
    
	struct Node* newNode = (struct Node*)malloc(sizeof(struct Node));
	newNode->data= data;
	newNode->next= NULL;
	return newNode;
}
//打印链表函数(仓库数据)
void printList(struct Node* headNode)
{
    
	struct Node* pMove = headNode->next;
	printf("商品编号\t名称\t类别\t进价\t售价\t数量\t供应商名字:\n");
	while(pMove)
	{
    
		printf("%d\t\t%s\t%s\t%.1f\t%.1f\t%d\t%s\n",pMove->data.num,pMove->data.name,pMove->data.type,pMove->data.inprice,pMove->data.outprice,pMove->data.many,pMove->data.soldmane);
		pMove = pMove->next;
	}
 } 
//打印链表函数(商品数据) 
void printListSimple(struct Node* headNode)
{
    
	struct Node* pMove = headNode->next;
	printf("名称\t类别\t售价\t数量\t供货商\n");
	while(pMove)
	{
    
		printf("%s\t%s\t%.1f\t%d\t%s\n",pMove->data.name,pMove->data.type,pMove->data.outprice,pMove->data.many,pMove->data.soldmane);
		pMove = pMove->next;
	}
 } 
//链表插入函数
void insertNodeByHead(struct Node* headNode,struct woodinfo data)
{
    
	struct Node* newNode = createNode(data);
	newNode->next = headNode->next;
	headNode->next = newNode; 
} 
//指定位置查找
struct Node* searchByName(struct Node* headNode,char* woodname)
{
    
	struct Node* posNode = headNode->next;
	while(posNode!=NULL&&strcmp(posNode->data.name,woodname))
	{
    
		posNode=posNode->next;
	}
	return posNode;
}
 
//指定位置删除
void deleteNodeByData(struct Node* headNode,char *name)
{
    
	struct Node* posLeftNode = headNode;
	struct Node*posNode = headNode->next;
	//商品名称是字符串,字符串比较函数 
	while (posNode !=NULL && strcmp(posNode->data.name,name))
	{
    
		posLeftNode = posNode;
		posNode = posLeftNode->next;
	}
	if(posNode ==NULL)
		return;
	else//删除代码 
	{
    
		printf("删除成功!\n"); 
		posLeftNode->next = posNode->next;
		free(posNode);
		posNode = NULL;
	}
}

//菜单模块
void menu() 
{
    
	printf("~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n");
	printf("~~~~~~~~~~~~~销售管理系统~~~~~~~~~~~~~~~~~~~\n");
	printf("0.退出销售管理系统\n");
	printf("1.进货\n");
	printf("2.退货\n");
	printf("3.仓库详细信息展示\n");
	printf("4.商品列表\n");
	printf("5.商品列表2.0(按价格高低)\n");
	printf("6.查找商品\n");
	printf("请输入(0~6):");
	printf("~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n");
}
//文件存操作
void saveInforFormFile(const char* fileName, struct Node* headNode)
{
    
		FILE* fp = fopen(fileName,"w");
		struct Node* pMove = headNode->next;
		while(pMove !=NULL)
		{
    
			fprintf(fp,"%d\t%s\t%s\t%.1f\t%.1f\t%d\t%s\n",pMove->data.num,pMove->data.name,pMove->data.type,pMove->data.inprice,pMove->data.outprice,pMove->data.many,pMove->data.soldmane); 
			pMove = pMove->next;
		}
		fclose(fp);
} 
//文件读操作
void readInfoFromFile(const char* fileName,struct Node* headNode)
{
    
	FILE* fp=fopen(fileName,"r");//第一次开始无文件创建文件
	if (fp==NULL)//创建文件
	{
    
		fp = fopen(fileName,"w+");
	} 
	struct woodinfo tempdata;
	while(fscanf(fp,"%d\t%s\t%s\t%f\t%f\t%d\t%s",tempdata.num,tempdata.name,tempdata.type,tempdata.inprice,tempdata.outprice,tempdata.many,tempdata.soldmane)!=EOF)
	{
    
		insertNodeByHead(list,tempdata);
	}
	fclose(fp);
	 
 } 
 //冒泡排序法
 void bubbleSortList(struct Node* headNode)
{
    
	for(struct Node* p = headNode->next;p!=NULL;p=p->next)
	{
    
		for(struct Node* q=headNode->next;q->next!=NULL;q=q->next)
		{
    
			if(q->data.outprice>q->next->data.outprice)
			{
    
				//交换值
				struct woodinfo tempdata = q->data; 
				q->data=q->next->data;
				q->next->data=tempdata;
				 
			}
		}
	}
	printListSimple(list); 
} 
//交互模块
void keyDown ()
{
    
	int userKey = 0;
	struct woodinfo tempwood;//产生一个临时的变量存储商品信息 
	struct Node* result =NULL;
	scanf("%d",&userKey);
	switch (userKey)
	{
    
	 case 0:
	 	printf("[退出]\n");
	 	printf("退出成功!\n");
	 	system("pause");
	 	exit(0);
	 	break;
	 case 1:
	 	printf("[进货ing]\n"); 
	 	printf("请依次输入:\n");
	 	printf("商品编号 名称	类别	进价	售价	数量	供应商名字:\n");
		scanf("%d%s%s%f%f%d%s",&tempwood.num,tempwood.name,tempwood.type,&tempwood.inprice,&tempwood.outprice,&tempwood.many,&tempwood.soldmane);
	 	insertNodeByHead(list, tempwood);
	 	saveInforFormFile("woodinfo.txt",list);
		break;
	 case 2:
	 	printf("[退货ing]\n");
	 	printf("请输入需要退货的商品名称:\n");
	 	scanf("%s",tempwood.name);
	 	deleteNodeByData(list,tempwood.name);
	 	saveInforFormFile("woodinfo.txt",list);
	 	printf("退货成功!\n");
		break;
	 case 3:
	 	printf("[仓库详细信息展示]\n");
	 	printList(list);
	 	break;
	 case 4:
	 	printf("[商品列表]\n");
	 	printListSimple(list);
	 	break;
	 case 5:
	    printf("[商品列表2.0(按价格高低)]\n");
	    bubbleSortList(list);
	 	break;	
	 case 6:
	 	printf("[查找商品ing]\n");
	 	printf("请输入需要查找的商品名称:\n");
		scanf("%s",tempwood.name);
		result = searchByName(list,tempwood.name);
		if(result==NULL)
		{
    
			printf("未找到相关商品!\n");
		}
		else
		{
    
			printf("商品编号	名称	类别	进价	售价	数量	供应商名字:\n");
			printf("%d\t\t%s\t%s\t%.1f\t%.1f\t%d\t%s\n",result->data.num,result->data.name,result->data.type,result->data.inprice,result->data.outprice,result->data.many,result->data.soldmane);
		}	
	} 
}

//主函数
int main() 
{
    
	list = createHead();//初始化全局链表 
	readInfoFromFile("woodinfo.txt",list);
	while(1)
	{
    
		menu(); 
		keyDown();
		system("pause");//防止闪屏 
		system("cls");//清屏 
	}
	system("pause");
	return 0;
 }

四.调试分析

⒈. 开始输入代码写为scanf(“%.1f”,&a),发现程序运行到该步骤总是自动退出,最后得知scanf的用法这样用会引起错误,修改为(“%f”),输出格式可以为printf(“%.f”)。

⒉. 自定义函数名在引用该函数时引用名发生错误,导致编译器无法识别,并提示需要定义改该函数,修改后即可正确运行。

⒊. 进行数据输出运用了格式符依旧无法进行数据的对齐,直到在未对齐的数据后多加了了个\t才实现数据的对齐。

⒋.Scanf()输入的%s时不需要取地址符&;

⒌.一开始引用FILE文件时,第一次运行皆正常,而一旦txt内存有数据后,再运行程序时会导致程序无法打开,无法正常运行。多次检测后发现为文档写操作中的fscanf中非字符未加取地址符号&,导致光标无法到达EOF,进入了死循环。重新加入&后,一切正常。

⒍.自定义函数放在了该函数调用的后面,导致从上而下的程序编译时报错显示未声明该函数,将自定义函数放在所有调用函数之前,即可正常编译运行。

五.总结分析

1.采用自定义函数按照模块的方式,一个模块一个模块的逐个针对,使整个程序会显得更加简洁,并会让主函数变得十分简洁,其余的步骤交个各个小函数模块进行操作。
2. 采用链表进行数据的储存可以使文件的删除更加方便,这是链表相较于数组的优越性,同时对于查找删除的操作也是更加方便,无需数组的逐个遍历。
3. 采用File文件对链表中的数据进行存储可以使得程序对于已填入的数据可更加方便的进行后续操作,无需重新输入,并可在原来存储的数据中进行增删查改的操作,使得程序的简便性更加强大。
4. 采用system(“pause”);语句可以防止闪屏,使得程序进行更加流畅;
5. 采用system(“cls”);语句可以在一次交互操作后清空屏幕(但会保留菜单项),使得程序的界面更加简洁明了,便于操作。

六.运行展示

详细信息展示功能:
菜单界面
在这里插入图片描述查找商品演示
在这里插入图片描述

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/m0_52381232/article/details/114162863

智能推荐

分布式光纤传感器的全球与中国市场2022-2028年:技术、参与者、趋势、市场规模及占有率研究报告_预计2026年中国分布式传感器市场规模有多大-程序员宅基地

文章浏览阅读3.2k次。本文研究全球与中国市场分布式光纤传感器的发展现状及未来发展趋势,分别从生产和消费的角度分析分布式光纤传感器的主要生产地区、主要消费地区以及主要的生产商。重点分析全球与中国市场的主要厂商产品特点、产品规格、不同规格产品的价格、产量、产值及全球和中国市场主要生产商的市场份额。主要生产商包括:FISO TechnologiesBrugg KabelSensor HighwayOmnisensAFL GlobalQinetiQ GroupLockheed MartinOSENSA Innovati_预计2026年中国分布式传感器市场规模有多大

07_08 常用组合逻辑电路结构——为IC设计的延时估计铺垫_基4布斯算法代码-程序员宅基地

文章浏览阅读1.1k次,点赞2次,收藏12次。常用组合逻辑电路结构——为IC设计的延时估计铺垫学习目的:估计模块间的delay,确保写的代码的timing 综合能给到多少HZ,以满足需求!_基4布斯算法代码

OpenAI Manager助手(基于SpringBoot和Vue)_chatgpt网页版-程序员宅基地

文章浏览阅读3.3k次,点赞3次,收藏5次。OpenAI Manager助手(基于SpringBoot和Vue)_chatgpt网页版

关于美国计算机奥赛USACO,你想知道的都在这_usaco可以多次提交吗-程序员宅基地

文章浏览阅读2.2k次。USACO自1992年举办,到目前为止已经举办了27届,目的是为了帮助美国信息学国家队选拔IOI的队员,目前逐渐发展为全球热门的线上赛事,成为美国大学申请条件下,含金量相当高的官方竞赛。USACO的比赛成绩可以助力计算机专业留学,越来越多的学生进入了康奈尔,麻省理工,普林斯顿,哈佛和耶鲁等大学,这些同学的共同点是他们都参加了美国计算机科学竞赛(USACO),并且取得过非常好的成绩。适合参赛人群USACO适合国内在读学生有意向申请美国大学的或者想锻炼自己编程能力的同学,高三学生也可以参加12月的第_usaco可以多次提交吗

MySQL存储过程和自定义函数_mysql自定义函数和存储过程-程序员宅基地

文章浏览阅读394次。1.1 存储程序1.2 创建存储过程1.3 创建自定义函数1.3.1 示例1.4 自定义函数和存储过程的区别1.5 变量的使用1.6 定义条件和处理程序1.6.1 定义条件1.6.1.1 示例1.6.2 定义处理程序1.6.2.1 示例1.7 光标的使用1.7.1 声明光标1.7.2 打开光标1.7.3 使用光标1.7.4 关闭光标1.8 流程控制的使用1.8.1 IF语句1.8.2 CASE语句1.8.3 LOOP语句1.8.4 LEAVE语句1.8.5 ITERATE语句1.8.6 REPEAT语句。_mysql自定义函数和存储过程

半导体基础知识与PN结_本征半导体电流为0-程序员宅基地

文章浏览阅读188次。半导体二极管——集成电路最小组成单元。_本征半导体电流为0

随便推点

【Unity3d Shader】水面和岩浆效果_unity 岩浆shader-程序员宅基地

文章浏览阅读2.8k次,点赞3次,收藏18次。游戏水面特效实现方式太多。咱们这边介绍的是一最简单的UV动画(无顶点位移),整个mesh由4个顶点构成。实现了水面效果(左图),不动代码稍微修改下参数和贴图可以实现岩浆效果(右图)。有要思路是1,uv按时间去做正弦波移动2,在1的基础上加个凹凸图混合uv3,在1、2的基础上加个水流方向4,加上对雾效的支持,如没必要请自行删除雾效代码(把包含fog的几行代码删除)S..._unity 岩浆shader

广义线性模型——Logistic回归模型(1)_广义线性回归模型-程序员宅基地

文章浏览阅读5k次。广义线性模型是线性模型的扩展,它通过连接函数建立响应变量的数学期望值与线性组合的预测变量之间的关系。广义线性模型拟合的形式为:其中g(μY)是条件均值的函数(称为连接函数)。另外,你可放松Y为正态分布的假设,改为Y 服从指数分布族中的一种分布即可。设定好连接函数和概率分布后,便可以通过最大似然估计的多次迭代推导出各参数值。在大部分情况下,线性模型就可以通过一系列连续型或类别型预测变量来预测正态分布的响应变量的工作。但是,有时候我们要进行非正态因变量的分析,例如:(1)类别型.._广义线性回归模型

HTML+CSS大作业 环境网页设计与实现(垃圾分类) web前端开发技术 web课程设计 网页规划与设计_垃圾分类网页设计目标怎么写-程序员宅基地

文章浏览阅读69次。环境保护、 保护地球、 校园环保、垃圾分类、绿色家园、等网站的设计与制作。 总结了一些学生网页制作的经验:一般的网页需要融入以下知识点:div+css布局、浮动、定位、高级css、表格、表单及验证、js轮播图、音频 视频 Flash的应用、ul li、下拉导航栏、鼠标划过效果等知识点,网页的风格主题也很全面:如爱好、风景、校园、美食、动漫、游戏、咖啡、音乐、家乡、电影、名人、商城以及个人主页等主题,学生、新手可参考下方页面的布局和设计和HTML源码(有用点赞△) 一套A+的网_垃圾分类网页设计目标怎么写

C# .Net 发布后,把dll全部放在一个文件夹中,让软件目录更整洁_.net dll 全局目录-程序员宅基地

文章浏览阅读614次,点赞7次,收藏11次。之前找到一个修改 exe 中 DLL地址 的方法, 不太好使,虽然能正确启动, 但无法改变 exe 的工作目录,这就影响了.Net 中很多获取 exe 执行目录来拼接的地址 ( 相对路径 ),比如 wwwroot 和 代码中相对目录还有一些复制到目录的普通文件 等等,它们的地址都会指向原来 exe 的目录, 而不是自定义的 “lib” 目录,根本原因就是没有修改 exe 的工作目录这次来搞一个启动程序,把 .net 的所有东西都放在一个文件夹,在文件夹同级的目录制作一个 exe._.net dll 全局目录

BRIEF特征点描述算法_breif description calculation 特征点-程序员宅基地

文章浏览阅读1.5k次。本文为转载,原博客地址:http://blog.csdn.net/hujingshuang/article/details/46910259简介 BRIEF是2010年的一篇名为《BRIEF:Binary Robust Independent Elementary Features》的文章中提出,BRIEF是对已检测到的特征点进行描述,它是一种二进制编码的描述子,摈弃了利用区域灰度..._breif description calculation 特征点

房屋租赁管理系统的设计和实现,SpringBoot计算机毕业设计论文_基于spring boot的房屋租赁系统论文-程序员宅基地

文章浏览阅读4.1k次,点赞21次,收藏79次。本文是《基于SpringBoot的房屋租赁管理系统》的配套原创说明文档,可以给应届毕业生提供格式撰写参考,也可以给开发类似系统的朋友们提供功能业务设计思路。_基于spring boot的房屋租赁系统论文