销售管理系统_手机销售信息管理系统 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

智能推荐

振弦式土压力计性能评估指南-程序员宅基地

文章浏览阅读134次,点赞2次,收藏5次。在长期的监测过程中,保持土压力计的性能稳定与准确至关重要。若读数变化与施加的压力成正比,且变化范围在允许误差内,则说明土压力计的灵敏度正常。反之,若读数变化不明显或不成比例,则可能是土压力计灵敏度下降,需要进行维修或更换。为了检查温度对土压力计的影响,可以在不同温度下对土压力计进行读数测试。为了方便对土压力计性能进行长期跟踪和分析,建议建立土压力计的数据存储与分析系统。确定振弦式土压力计性能是否正常需要从外观检查、零点漂移检查、灵敏度检查、温度影响检查、校准与比对以及数据存储与分析等多个方面进行综合评估。

MSYS2使用笔记_msys2是干嘛的-程序员宅基地

文章浏览阅读9.9k次。MSYS2是一个体验非常好的linux模拟环境,可以移植大多数linux上面的程序,起源于cygwin。虽然官方网站也提供了安装包,一键安装,但是整个软件包太大了,我不太喜欢大而全的东西,更喜欢小而精的玩意。这里有一个非常好的镜像网站,http://mirrors.ustc.edu.cn/msys2/可以下载MSYS2的所有组件,以及所有版本,简直太好了。下载runtime + coreutil ..._msys2是干嘛的

web.xml详解-程序员宅基地

文章浏览阅读113次。&lt;?xml version="1.0" encoding="UTF-8"?&gt;&lt;web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xsi:schemaLocation="http://j_web.xml

设置freemarker缓存处理template_update_delay_freemarker template_update_delay-程序员宅基地

文章浏览阅读4.5k次。在配置文件中配置spring.freemarker.settings.template_update_delay=0 _freemarker template_update_delay

关于上传图片是提示报错信息 Uncaught TypeError:Cannot red property ‘fildeList‘ of undefiend_wangeditor 上传图片报错wangeditor.min.js:16 uncaught typ-程序员宅基地

文章浏览阅读178次。关于上传图片是提示报错信息 Uncaught TypeError:Cannot red property 'fildeList' of undefiend_wangeditor 上传图片报错wangeditor.min.js:16 uncaught typeerror: cannot read

Solr实战之(一)Solr入门_solr建模-程序员宅基地

文章浏览阅读894次。(1)当今,软件架构所面临的一个主要挑战是处理广泛的全球群体消费和产生的大数据;为解决现代web应用的可扩展性和可用性需求,NoSQL技术受到越来越多的关注,Apache下的Solr便是一种NoSQL技术。 (2)Solr是可扩展的,开箱即用的企业级搜索引擎,用来搜索大规模文本数据并根据相关度排序结果。 (3)Solr构建在Apache的Lucene上,Lucene是基于Java的开源信息检索_solr建模

随便推点

VMware 7.0安装教程_vmware7.0u2安装教程-程序员宅基地

文章浏览阅读1.2k次。VMware 7.0是VMware官方在2009年发布的新版虚拟机,VMware 7.0以其强大的功能和简单易用的操作赢得了许多网友的青睐,本文将向大家展示VMware7.0安装教程以及VMware7.0安装Widonws系统的详细教程。 首先需要下载VMware 7.0,在官网下载的方法请见:虚拟机下载 下载完成后双击VMware 7.0安装包,开始进入安装向导: _vmware7.0u2安装教程

”文档写作能力“ 是软件开发工程师必备的素质之一!_文档编写能力举例说明-程序员宅基地

文章浏览阅读6k次,点赞3次,收藏4次。本文档由Markdown语法编辑器编辑完成!1. 概述:不知不觉中,从刚毕业时的毛头小伙,到现在的油腻中年程序员,已经过了将近五年了。在这五年中,做过的项目,大小加起来也有十几个了吧,写过的代码量5万行应该差不多了吧。在这五年的工作过程中,除去软件开发能力的提升,系统和软件架构能力的扩展外,越来越让我感觉重要的,就是可能被大部分程序猿和程序媛们忽略的能力——文档写作能力!这里的文档..._文档编写能力举例说明

小猿圈Python之实现得到当前时间偏移day天后的日期方法-程序员宅基地

文章浏览阅读120次。对于Python相信很多小伙伴都不陌生吧,从语言排行榜十以外到现在的第三,可见python是现在很热门的一种语言,Python开发的人都在一直的增加,今天小猿圈Python就分享一个实现得到当前时间偏移day天后的日期方法,希望对你学习Python有所帮助。 如下所示: import da..._python输出时间后移

大规模数据处理的演化历程(2003-2018)-程序员宅基地

文章浏览阅读222次。转自:https://www.iteblog.com/archives/2430.html本文翻译自《Streaming System》最后一章《The Evolution of Large-Scale Data Processing》,在探讨流式系统方面本书是市面上难得一见的深度书籍,非常值得学习。大数据如果从 Google 对外发布 MapReduce 论文算起,已经前后跨越..._the evolution of massive-scale data processing 幻灯片

干货 应用阿里AI一句话识别 java 实现语音实时识别_阿里语音一句话识别-程序员宅基地

文章浏览阅读1.5k次。首次讲讲思路,如果说不定大佬们也可以自己完成 ,如果大佬们懒得弄那就直接看这里看这里上面我已经实现了语音的实时录入检测识别并且附带了录入和识别的子项目1.)本地语音的实时录入、并检测是否有语音录入判断是否休眠package com.wqc.sound;import java.io.ByteArrayInputStream;import java.io.ByteArrayO..._阿里语音一句话识别

结对编程-神奇的力量-程序员宅基地

文章浏览阅读125次。《敏捷软件开发实践》之结对编程 还记得入职之前,HR跟我说,你面试的时候是.NET,不过根据现在公司项目的状况,你很可能会去做Java,你愿意么?我想了想,从来没写过实际的Java项目啊,Hello world也是好几年之前了,这能行么?但是我又很想得到这份工作,然后就说:Let me try。就这样,我这么一个.NET程序员就跑到Java Team打酱油去了。现在,半年快过去了,做了半年的基于..._ping-pong 结对编程

推荐文章

热门文章

相关标签