C语言-超市仓库管理系统的设计与实现

C语言-超市仓库管理系统的设计与实现

第一个博客~
超市仓库管理系统的设计与实现
问题描述:实现一个小型仓库管理系统,完成商品的入库,出库,查询等功能。
物品信息说明:物品代码,物品名称,物品总量,商品价格、保质期时间、入库时间
具体功能说明:
(1)物品入库:输入物品信息进入仓库;
(2)物品出库:输入出库信息进行物品出库;
(3)查询:输入商品代码或名称查询库存信息,输入入库日期查询所有当天入库商品信息,输入出库日期查询所有当天出库商品信息,范围查询;
(4)保质期查询:显示所有过保质期的商品,显示快到保质期时间所有商品;
(5)数据的持久化操作:存文件和读文件;
(6)在需求分析阶段完成未尽功能需求,适当扩充功能(至少扩充3-5个功能)。1.管理员登录 2.添加 删除管理员 3.商品信息修改 4.商品信息统计

系统需求分析

  1. 超市仓库管理系统介绍
    随着计算机技术的不断发展,为了方便超市仓库管理人员对超市商品、供应商、入/出库等进行高效的管理,本超市仓库管理系统应运而生。本系统要求系统界面友好、使用简单、提供对商品信息、管理员信息和商品流通情况的编辑、查询、统计报表等全面的数据管理功能。
  2. 超市仓库管理系统用户说明
    本系统有两类用户:超级管理员和普通管理员。
    超级管理员可以进行登录并进行管理员账号的添加和删除。普通管理员可以进行登录,商品入/出库信息管理,商品信息修改、查询、排序,商品过期统计功能,商品库存报警功能。
  3. 超市仓库管理系统功能介绍
    C语言-超市仓库管理系统的设计与实现_第1张图片

系统主要功能包括管理员模块,商品入/出库模块,商品信息管理模块,具体说明如下:
1)管理员模块:超级管理员可以进行管理员的添加和删除,普通管理员可以进行登录,商品入/出库信息管理,商品信息修改、查询、排序,商品过期统计功能,商品库存报警功能。
2)商品入/出库模块:主要完成物品信息入出仓库(从文件中读取入库数据,出库数据)。
3)商品信息管理模块:
1.商品数据的读写:主要完成从文件中读取商品数据和向文件中写入最终商品数据。
2.查询:主要完成输入商品代码或名称查询库存信息,输入入库日期查询所有当天入库商品信息,输入出库日期查询所有当天出库商品信息,范围查询。保质期查询:显示所有过保质期的商品,显示快到保质期时间所有商品。
3.修改:主要完成修改指定商品信息的功能。
4.排序:主要完成对商品按商品库存升序的功能。
5.统计:主要完成统计所有物品信息的功能。
信息的永久化处理:所有内存数据应保存到文件中,做永久化处理,以便数据不会丢失。

系统总体设计

  1. 数据结构设计
    (1)管理员对象:管理员账号,管理员密码,指向下一个管理员的指针
typedef struct admin
{
     
	int admin;						//管理员账号
	int password;				    //管理员密码
	struct admin* next;				//指向下一个管理员的指针
}Admin;

(2)商品生产日期对象:年,月,日

typedef struct date					//生产日期结构体
{
     
   int year;
   int month;
   int day;
}Date;

(3)商品对象:商品代码,商品名称,商品库存,商品价格,保质期时间,入库数目,出库数目,最终库存,是否过期标志,库存是否小于警戒值标志,指向下一个商品的指针,生产日期,入库时间,出库时间。

typedef struct goods
{
     
   int good_id;					    //商品代码
   char name[20];					//商品名称
   int stock;						//商品库存
   int price;						//商品价格
   int quality_time;				//保质期时间
   int in_warehouse;				//入库数目
   int out_warehouse;				//出库数目
   int sum_warehouse;				//最终库存

   int state_over;					//是否过期标志
   int state_warning;				//库存是否小于警戒值标志

   struct goods* next;				//指向下一个物品的指针
   struct date production_time;	    //生产日期
   struct date in_time;			    //入库时间
   struct date out_time;		    //出库时间
}Goods;

系统详细设计与实现

3.1读管理员文件
Admin* Read_AdminFile(FILE* fp)
处理流程:传入文件指针fp,先申请头结点,当fp不为空时,创建一个结点,读入管理员账号密码,最后返回头指针。
3.2写管理员文件
void Save_To_AdminFile(Admin* head)
处理流程:传入链表头指针,只读方式打开管理员文件,当链表不为空时写入管理员数据,最后关闭文件,并显示保存成功,保存了几名管理员数据信息。
3.3添加管理员
Admin* InsertAdmin(Admin* head)
处理流程:传入链表头指针,新创建一个结点,输入管理员数据,将新结点链入链表头(头插法),最后显示新管理员添加成功信息。
3.4删除管理员
Admin* DeleteAdmin(Admin* head, int admin)
处理流程:传入链表头指针和管理员账号,搜索是否有此管理员,若有则free()删除结点,若无则显示无此管理员信息。
3.5销毁管理员链表释放内存
void DestroyAdminLine(Admin* head)
处理流程:传入文件头指针,若头指针不为空逐个结点销毁释放内存。
3.6判断是否为闰年
int isPrime(int year)
处理流程:传入一个年份,若为闰年返回1,否则返回0。
3.7计算两个日期相差天数
int dateDiff(Date mindate, Date maxdate)
处理流程:先将两个日期设置为前小后大,再计算年份,mindate到maxdate中的年份为闰年则加366,否则加365,再计算月份,若年份为闰年,则调用闰年月份天数数组,否则调用非闰年月份天数数组,最后返回两个日期相差天数。
3.8判断商品库存是否低于警戒值
int pan_goods_warning(Goods* p)
处理流程:传入商品指针,若商品库存大于库存警戒值则返回false,否则返回true。
3.9判断商品库存是否低于警戒值
int pan_goods_warning(Goods* p)
处理流程:传入商品指针,若商品库存大于库存警戒值则返回false,否则返回true。
3.10显示表头
void printhead()
处理流程:显示商品信息表头。
3.11显示表体
void printgoods(Goods* p)
处理流程:传入商品指针,计算商品最终库存,计算商品库存是否低于警戒值,计算商品是否过期,显示商品信息。
3.12分页显示指定页面商品信息
void getpage(Goods* head, int page)
处理流程:传入链表头指针,页码,设置行号计数器row为0,起始行start,结束行end,当链表不为空时,若row在start与end之间,则显示商品信息。
3.13分页显示全部商品信息
void GoodsShow(Goods* head)
处理流程:传入链表头指针,先计算显示总页数,调用getpage()函数显示当前页,根据当前页的页码设置分页菜单并显示。
3.14查询商品库存
Goods* GoodsStock_Query(Goods* head)
处理流程:传入商品头指针,函数提供2种查询方式(按商品代码查询,按商品名称查询)。如果选择按商品代码查询,对商品代码进行检索,若找到则输出该商品的全部信息;按商品名称查询类似。。
3.15查询当天入/出库商品
Goods* GoodsInOut_Query(Goods* head)
处理流程:传入商品头指针,函数提供2种查询方式(按入库日期查询,按出库日期查询)。根据所输入的日期遍历链表,若查询成功则输出该商品的全部信息。
3.16查询商品保质期
void GoodsQualityTime(Goods* head)
处理流程:传入商品头指针,函数提供2种查询方式(1-显示所有过保质期的商品,2-显示所有快到保质期的商品)。1-调用判断商品过期函数,遍历链表,若过期则显示该商品信息。2-调用计算两日期相差天数函数,遍历链表,若相差天数小于10则视为快过期并显示该商品信息。
3.17商品信息修改
Goods* Goods_Edit(Goods* head)
处理流程:传入商品头指针,先调用商品信息查询函数,若有该商品,则输入该商品的修改信息,若无,则显示无该商品记录信息。
3.18商品信息排序(按商品库存升序排序)
void Goods_Sort(Goods* head)
处理流程:传入商品头指针,用冒泡排序将商品按商品库存排序。
3.19商品入库
Goods* In_WareHouse(Goods* head)
处理流程:传入商品头指针,当文件指针不为空时,读入商品入库数据链入链表,返回商品链表头指针。
3.20商品出库
Goods* Out_WareHouse(Goods* head)
处理流程:传入商品头指针,当文件指针不为空时,读入商品出库数据链入链表,返回商品链表头指针。
3.21判断商品在入库时间是否过期
int pan_goodsIn_over(Goods* head)
处理流程:传入商品头指针,调用dateDiff()函数计算商品生产日期到入库日期的相差天数与保质期相比较,若大于则过期返回1,否则返回0。
3.22判断商品在出库时间是否过期
int pan_goodsOut_over(Goods* head)
处理流程:传入商品头指针,调用dateDiff()函数计算商品生产日期到出库日期的相差天数与保质期相比较,若大于则过期返回1,否则返回0。
3.23读商品文件
Goods* Read_GoodsFile(FILE* fp)
处理流程:传入文件指针fp,先申请头结点,当fp不为空时,创建一个结点,读入商品信息,最后返回链表头指针。
3.24写商品文件
void Save_To_GoodsFile(Goods* head)
处理流程:传入链表头指针,只读方式打开商品文件,当链表不为空时写入商品数据,最后关闭文件,并显示保存成功,保存了几项商品数据信息。
3.25销毁商品链表释放内存
void DestroyGoodsLine(Goods* head)
处理流程:传入文件头指针,若头指针不为空逐个结点销毁释放内存。
3.26读商品文件
Goods* Read_GoodsFile(FILE* fp)
处理流程:传入文件指针fp,先申请头结点,当fp不为空时,创建一个结点,读入商品信息,最后返回链表头指针。

源代码

源文件包含admin.h,date.h,goods.h,超市仓库管理系统的设计与实现.c,admin.txt,goods.txt,stockin.txt,stockout.txt

//admin.h
#pragma once

#include <stdio.h>
#include <malloc.h>
#pragma warning(disable:6031)
int admin_length = 0;				//管理员链表的长度
#define Super_Admin 123             //超级管理员账号
#define Super_Password 456			//超级管理员密码

typedef struct admin
{
     
   int admin;						//管理员账号
   int password;				    //管理员密码
   struct admin* next;				//指向下一个管理员的指针
}Admin;

//读管理员文件
Admin* Read_AdminFile(FILE* fp)
{
     
   int i = 1;
   Admin* head = NULL, * newadmin, * p2 = NULL;
   head = (Admin*)malloc(sizeof(Admin));
   head->next = NULL;

   while (!feof(fp)) {
     
   	newadmin = (Admin*)malloc(sizeof(Admin));
   	newadmin->next = NULL;
   	fscanf(fp, "%d%d", &newadmin->admin, &newadmin->password);
   	admin_length++;
   	if (i == 1) head->next = newadmin;
   	else p2->next = newadmin;
   	p2 = newadmin; i++;
   }
   return head;
}

//写管理员文件
void Save_To_AdminFile(Admin* head)
{
     
   FILE* fp;
   int num = 0;
   Admin* p;
   p = head->next;
   if ((fp = fopen("admin.txt", "w")) == NULL) {
     
   	printf("无法打开数据文件!\n");
   	return;
   }
   while (p != NULL) {
     
   	fprintf(fp, "%d %d\n", p->admin, p->password);
   	num++;
   	p = p->next;
   }
   fclose(fp);
   printf("保存结束,共保存了%d名管理员数据!\n", num);
}

//添加管理员
Admin* InsertAdmin(Admin* head)    
{
     
   Admin* p, * pnew;
   p = head;
   while (p->next != NULL) {
      p = p->next; }
   pnew = (Admin*)malloc(sizeof(Admin));
   if (pnew == NULL) {
      printf("不能成功分配到存储块!\n"); exit(0); }
   pnew->next = NULL;
   printf("请输入新管理员的账号:\n");
   scanf("%d", &pnew->admin);
   printf("请输入新管理员的密码:\n");
   scanf("%d", &pnew->password);
   p->next = pnew;
   admin_length++;
   printf("新管理员添加成功!\n");
   return head;
}

//删除管理员
Admin* DeleteAdmin(Admin* head, int admin)
{
     
   Admin* p1 = head, * p2 = head;
   while ((p1->admin != admin) && p1->next != NULL) {
      p2 = p1; p1 = p1->next; }
   if (p1->admin == admin) {
     
   	if (p1 == head) head = p1->next;
   	else p2->next = p1->next;
   	free(p1);
   	printf("删除成功!\n");
   }
   else {
     
   	printf("无此管理员!\n");
   }
   return head;
}

//销毁管理员链表释放内存
void DestroyAdminLine(Admin* head)
{
     
   Admin* p, * q1, * q2;
   p = head;
   q1 = p->next;
   if (q1 == NULL) return;
   q2 = q1->next;
   while (q1->next)
   {
     
   	free(q1);
   	q1 = q2;
   	q2 = q2->next;
   }
}
//date.h
#pragma once

typedef struct date					//生产日期结构体
{
     
   int year;
   int month;
   int day;
}Date;

//判断是否为闰年
int isPrime(int year)
{
     
   if ((year % 4 == 0 && year % 100 != 0) || year % 400 == 0) {
     
   	return 1;
   }
   else
   	return 0;
}

//计算两个日期相差天数
int dateDiff(Date mindate, Date maxdate)
{
     
   int days = 0, flag = 1;
   int primeMonth[12] = {
      31,29,31,30,31,30,31,31,30,31,30,31 };
   int notPrimeMonth[12] = {
      31,28,31,30,31,30,31,31,30,31,30,31 };

   Date tmp;
   if ((mindate.year > maxdate.year) || (mindate.year == maxdate.year && mindate.month > maxdate.month) || (mindate.year == maxdate.year && mindate.month == maxdate.month && mindate.day > maxdate.day))
   {
     
   	tmp = mindate;
   	mindate = maxdate;
   	maxdate = tmp;
   }

   int maxmonth, minmonth;

   if (maxdate.month < mindate.month)
   {
     
   	maxmonth = mindate.month;
   	minmonth = maxdate.month;
   	flag = -1;
   }
   else
   {
     
   	maxmonth = maxdate.month;
   	minmonth = mindate.month;
   	flag = 1;
   }

   for (int j = mindate.year;j < maxdate.year;++j)
   {
     
   	if (isPrime(j) == 1)
   	{
     
   		days += 366;
   	}
   	else
   		days += 365;
   }

   int day;
   if (isPrime(maxdate.year) == 1)
   {
     

   	for (int i = minmonth;i < maxmonth;i++)
   	{
     
   		day = primeMonth[i - 1] * flag;
   		days = days + day;
   	}
   	days = days + maxdate.day - mindate.day;
   }
   else
   {
     
   	for (int i = minmonth;i < maxmonth;i++)
   	{
     
   		day = notPrimeMonth[i - 1] * flag;
   		days = days + day;
   	}
   	days = days + maxdate.day - mindate.day;
   }
   return days;
}
//goods.h
#pragma once
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <malloc.h>
#include "date.h"
#pragma warning(disable:6031)
#pragma warning(disable:4996)

#define pagesize 10                 //页长度 10
#define warning_warehouse 100       //库存警戒值
#define true 1
#define false 0
int goods_length = 0;				//商品链表的长度

typedef struct goods
{
     
   int good_id;					//商品代码
   char name[20];					//商品名称
   int stock;						//商品库存
   int price;						//商品价格
   int quality_time;				//保质期时间
   int in_warehouse;				//入库数目
   int out_warehouse;				//出库数目
   int sum_warehouse;				//最终库存

   int state_over;					//是否过期标志
   int state_warning;				//库存是否小于警戒值标志

   struct goods* next;				//指向下一个物品的指针
   struct date production_time;	//生产日期
   struct date in_time;			//入库时间
   struct date out_time;			//出库时间
}Goods;

//判断商品库存是否低于警戒值
int pan_goods_warning(Goods* p)
{
     
   if (p->stock >= warning_warehouse)
   	return false;
   else
   	return true;
}

//显示表头
void printhead()
{
     
   printf("商品代码  商品名称  商品价格  原始库存  生产日期  入库数目  入库日期  出库数目  出库日期  最终库存  保质期时间  是否低于警戒值  入库时是否过期  出库时是否过期  (0-否 1-是)\n");
}

//显示表体
void printgoods(Goods* p)
{
     
   int in = 0, out = 0;
   p->sum_warehouse = p->stock + p->in_warehouse - p->out_warehouse;
   p->state_warning = pan_goods_warning(p);
   in = pan_goodsIn_over(p);
   out = pan_goodsOut_over(p);
   printf("%5d %5s %5d元 %5d %d-%d-%d %5d %d-%d-%d %5d %d-%d-%d %5d %5d %5d %5d %5d\n", p->good_id, p->name, p->price, p->stock, p->production_time.year, p->production_time.month, p->production_time.day, p->in_warehouse, p->in_time.year, p->in_time.month, p->in_time.day, p->out_warehouse, p->out_time.year, p->out_time.month, p->out_time.day, p->sum_warehouse, p->quality_time, p->state_warning, in, out);
}

//分页显示指定页面商品信息
void getpage(Goods* head, int page)
{
     
   int row = 0;                                  //行号计数器:初值为0
   int start = (page - 1) * pagesize + 1;        //页行号下限:开始行
   int end = start + pagesize - 1;               //页行号上限:结束行
   Goods* p;
   p = head->next;
   printhead();
   while (p != NULL) {
     
   	row++;
   	if (row >= start && row <= end) {
     
   		printgoods(p);
   	}
   	else if (row > end) 
   		break;
   	p = p->next;
   }
}

//分页显示全部商品信息
void GoodsShow(Goods* head)
{
     
   int page = 1, total_page, error, t;
   if (goods_length == 0) {
     
   	printf("没有商品信息数据!\n");
   }
   if (goods_length % 10 == 0) {
     
   	total_page = goods_length / 10;
   }
   else {
     
   	total_page = goods_length / 10 + 1;
   }
   while (1) {
     
   	fflush(stdin);											//清空输入缓冲区
   	if (goods_length == 0) break;
   	printf("\n当前第%d页,总共%d页\n", page, total_page);
   	getpage(head, page);
   	if (total_page == 1) break;
   	else if (page == 1)
   	{
     
   		printf("分页菜单:3-下一页  4-尾页  5-返回\n请输入菜单编号(3-5):");
   		do {
     
   			fflush(stdin);
   			scanf("%d", &t);
   			switch (t) {
     
   			case 3:page++; error = 0; system("cls"); break;
   			case 4:page = total_page; error = 0; system("cls"); break;
   			case 5:return;
   			default:error = 1; printf("菜单编号输入错误,请输入菜单编号(3-5):"); break;
   			}
   		} while (error);
   	}
   	else if (page == total_page) {
     
   		printf("分页菜单:1-首页  2-上一页  5-返回\n请输入菜单编号(1、2、5):");
   		do {
     
   			scanf("%d", &t);
   			switch (t) {
     
   			case 1:page = 1; error = 0; system("cls"); break;
   			case 2:page--; error = 0; system("cls"); break;
   			case 5:return;
   			default:error = 1; printf("菜单编码输入错误,请输入菜单编号(1、2、5):"); break;
   			}
   		} while (error);
   	}
   	else {
     
   		printf("分页菜单:1-首页  2-上一页  3-下一页  4-尾页  5-返回\n");
   		printf("请输入菜单编号:");
   		do {
     
   			fflush(stdin);
   			scanf("%d", &t);
   			switch (t) {
     
   			case 1:page = 1; error = 0; system("cls"); break;
   			case 2:page--; error = 0; system("cls"); break;
   			case 3:page++; error = 0; system("cls"); break;
   			case 4:page = total_page; error = 0; system("cls"); break;
   			case 5:return;
   			default:error = 1; printf("菜单编码输入错误,请输入菜单编号(1-5):"); break;
   			}
   		} while (error);
   	}
   }
}

//查询商品库存
Goods* GoodsStock_Query(Goods* head)
{
     
   int choice, id;
   char name[20];
   Goods* p;
   p = head;
   printf("*          1-按商品代码查询          2-按商品名称查询          *\n");
   scanf("%d", &choice);
   if (choice == 1) {
     
   	printf("请输入要查询商品的商品代码:\n");
   	scanf("%d", &id);
   	while ((p->good_id != id) && (p->next != NULL))  p = p->next;
   	if (p->good_id != id) p = NULL;
   	else {
     
   		printhead();
   		printgoods(p);
   	}
   	return p;
   }
   else if (choice == 2) {
     
   	printf("请输入要查询商品的商品名称:\n");
   	scanf("%s", name);
   	while ((strcmp(name, p->name) != 0) && (p->next != NULL))  p = p->next;
   	if (strcmp(name, p->name) != 0) p = NULL;
   	else {
     
   		printhead();
   		printgoods(p);
   	}
   	return p;
   }
   return head;
}

//查询当天入/出库商品
Goods* GoodsInOut_Query(Goods* head)
{
     
   int choice;
   int year, month, day;
   Goods* p;
   p = head;
   printf("*            1-输入入库日期查询当天所有入库商品信息            *\n");
   printf("*            2-输入出库日期查询当天所有出库商品信息            *\n");
   scanf("%d", &choice);
   if (choice == 1) {
     
   	printf("请输入入库日期(输入格式2001 2 3):\n");
   	scanf("%d%d%d", &year, &month, &day);
   	printhead();
   	while (p->next != NULL) {
     
   		if (p->in_time.year == year && p->in_time.month == month && p->in_time.day == day)
   			printgoods(p);
   		p = p->next;
   	}
   }
   else if (choice == 2) {
     
   	printf("请输入出库日期(输入格式2001 2 3):\n");
   	scanf("%d%d%d", &year, &month, &day);
   	printhead();
   	while (p->next != NULL) {
     
   		if (p->out_time.year == year && p->out_time.month == month && p->out_time.day == day)
   			printgoods(p);
   		p = p->next;
   	}
   }
   return head;
}

//查询商品保质期
void GoodsQualityTime(Goods* head)
{
     
   int choice;
   Date d;
   Goods* p;
   p = head->next;
   printf("*  1-显示所有过保质期的商品     2-显示快到保质期时间所有商品   *\n");
   scanf("%d", &choice);
   if (choice == 1) {
     
   	printhead();
   	while (p != NULL) {
     
   		if ((pan_goodsIn_over(p) == 1) || (pan_goodsOut_over(p) == 1)) {
     
   			printgoods(p);
   		}
   		p = p->next;
   	}
   }
   else if (choice == 2) {
     
   	printf("请输入当天日期:\n");
   	scanf("%d%d%d", &d.year, &d.month, &d.day);
   	printhead();
   	while (p != NULL) {
     
   		if ((dateDiff(p->production_time, d) - p->quality_time) <= 10) {
     
   			printgoods(p);
   		}
   		p = p->next;
   	}
   }
}

//商品信息修改
Goods* Goods_Edit(Goods* head)
{
     
   Goods* p;
   p = head;
   p = GoodsStock_Query(p);
   if (p == NULL) printf("无商品记录!\n");
   else {
     
   	printf("请输入商品修改数据:\n");
   	printf("商品代码  商品名称  商品库存  商品价格  商品保质期时间  商品入库数目  商品出库数目:\n");
   	scanf("%d%s%d%d%d%d%d", &p->good_id, p->name, &p->stock, &p->price, &p->quality_time, &p->in_warehouse, &p->out_warehouse);
   	getchar();
   	printf("请输入生产日期(输入格式2001 2 3):\n");
   	scanf("%d%d%d", &p->production_time.year, &p->production_time.month, &p->production_time.day);
   	getchar();
   	printf("请输入入库日期(输入格式2001 2 3):\n");
   	scanf("%d%d%d", &p->in_time.year, &p->in_time.month, &p->in_time.day);
   	getchar();
   	printf("请输入出库日期(输入格式2001 2 3):\n");
   	scanf("%d%d%d", &p->out_time.year, &p->out_time.month, &p->out_time.day);
   	getchar();
   	if (dateDiff(p->production_time, p->in_time) > p->quality_time) {
     
   		p->state_over = 1;
   	}
   	else if (dateDiff(p->production_time, p->out_time) > p->quality_time) {
     
   		p->state_over = 1;
   	}
   	else
   		p->state_over = 0;
   	p->sum_warehouse = p->stock + p->in_warehouse - p->out_warehouse;
   	p->state_warning = pan_goods_warning(p);
   	printf("数据修改成功!\n");
   }
   return head;
}

//商品信息排序(按商品库存升序排序)
void Goods_Sort(Goods* head)
{
     
   Goods* p1;
   Goods* p2;
   p1 = NULL;
   p2 = head->next;
   int i, temp_id, temp_stock, temp_price, temp_quality_time, temp_in_warehouse, temp_out_warehouse, temp_sum_warehouse;
   char temp_name[20];
   if (p2 != NULL) {
     
   	for (i = 0; i < goods_length-1; i++) {
     
   		p1 = head->next;
   		p2 = head->next->next;
   		while (p2 != NULL) {
     
   			if (p1->stock > p2->stock) {
     
   				temp_id = p1->good_id; temp_stock = p1->stock; temp_price = p1->price; temp_quality_time = p1->quality_time; temp_in_warehouse = p1->in_warehouse; temp_out_warehouse = p1->out_warehouse; temp_sum_warehouse = p1->sum_warehouse; strcpy(temp_name, p1->name);
   				p1->good_id = p2->good_id; p1->stock = p2->stock; p1->price = p2->price; p1->quality_time = p2->quality_time; p1->in_warehouse = p2->in_warehouse; p1->out_warehouse = p2->out_warehouse; p1->sum_warehouse = p2->sum_warehouse; strcpy(p1->name, p2->name);
   				p2->good_id = temp_id; p2->stock = temp_stock; p2->price = temp_price; p2->quality_time = temp_quality_time; p2->in_warehouse = temp_in_warehouse; p2->out_warehouse = temp_out_warehouse; p2->sum_warehouse = temp_sum_warehouse; strcpy(p2->name, temp_name);
   			}
   			p1 = p1->next; p2 = p2->next;
   		}
   	}
   }
   p1 = head->next;
   //判断商品是否过期 库存是否低于警戒值
   while (p1 != NULL) {
     
   	if (dateDiff(p1->production_time, p1->in_time) > p1->quality_time) {
     
   		p1->state_over = 1;
   	}
   	else if (dateDiff(p1->production_time, p1->out_time) > p1->quality_time) {
     
   		p1->state_over = 1;
   	}
   	else p1->state_over = 0;
   	p1->state_warning = pan_goods_warning(p1);
   	p1 = p1->next;
   }
}

//商品入库
Goods* In_WareHouse(Goods* head)
{
     
   FILE* fp;
   Goods* p;
   p = head->next;
   fp = fopen("stockin.txt", "r");
   if (fp == NULL) {
      printf("商品入库文件打开错误!\n"); exit(0); }
   while (!feof(fp)) {
     
   	fscanf(fp, "%d%d%d%d%d", &p->good_id, &p->in_warehouse, &p->in_time.year, &p->in_time.month, &p->in_time.day);
   	p->sum_warehouse = p->stock + p->in_warehouse;
   	p->state_over = pan_goodsIn_over(p);
   	p = p->next;
   }
   return head;
}

//商品出库
Goods* Out_WareHouse(Goods* head)
{
     
   FILE* fp;
   Goods* p;
   p = head->next;
   fp = fopen("stockout.txt", "r");
   while (!feof(fp)) {
     
   	fscanf(fp, "%d%d%d%d%d", &p->good_id, &p->out_warehouse, &p->out_time.year, &p->out_time.month, &p->out_time.day);
   	p->sum_warehouse = p->stock - p->out_warehouse;
   	p->state_over = pan_goodsOut_over(p);
   	p = p->next;
   }
   return head;
}

//判断商品在入库的时间是否过期
int pan_goodsIn_over(Goods* head)
{
     
   Goods* p;
   p = head;
   int state;
   if (dateDiff(p->production_time, p->in_time) > p->quality_time)
   	state = 1;
   else
   	state = 0;//0-商品未过期,1-商品已过期
   return state;
}

//判断商品在出库的时间是否过期
int pan_goodsOut_over(Goods* head)
{
     
   Goods* p;
   p = head;
   int state;
   if (dateDiff(p->production_time, p->out_time) > p->quality_time)
   	state = 1;
   else
   	state = 0;//0-商品未过期,1-商品已过期
   return state;
}

//读商品文件
Goods* Read_GoodsFile(FILE* fp)
{
     
   int i = 1;
   Goods* head = NULL, * newgoods, * p2 = NULL;
   head = (Goods*)malloc(sizeof(Goods));
   
   head->next = NULL;
   while (!feof(fp)) {
     
   	newgoods = (Goods*)malloc(sizeof(Goods));
   	newgoods->next = NULL;
   	//读入商品代码,商品名称,商品库存,商品价格,商品保质期时间,商品入库数目,商品出库数目,最终库存,商品生产日期,商品是否过期标志,商品库存是否低于警戒值标志
   	fscanf(fp, "%d%s%d%d%d%d%d%d%d%d%d%d%d",
   		&newgoods->good_id, newgoods->name, &newgoods->stock, &newgoods->price,
   		&newgoods->quality_time, &newgoods->in_warehouse, &newgoods->out_warehouse, &newgoods->sum_warehouse,
   		&newgoods->production_time.year, &newgoods->production_time.month, &newgoods->production_time.day,
   		&newgoods->state_over, &newgoods->state_warning);
   	if (newgoods->stock <= warning_warehouse) {
     
   		newgoods->state_warning = 1;
   	}
   	goods_length++;
   	if (i == 1) head->next = newgoods;
   	else p2->next = newgoods;
   	p2 = newgoods; i++;
   }
   return head;
}

//写商品文件
void Save_To_GoodsFile(Goods* head)
{
     
   FILE* fp;
   int num = 0;
   Goods* p;
   p = head->next;
   if ((fp = fopen("goods.txt", "w")) == NULL) {
     
   	printf("无法打开数据文件!\n");
   	return;
   }
   while (p != NULL) {
     
   	fprintf(fp, "%d %s %d %d %d %d %d %d %d %d %d %d %d\n", 
   		p->good_id, p->name, p->stock, p->price, 
   		p->quality_time, p->in_warehouse, p->out_warehouse, p->sum_warehouse,
   		p->production_time.year, p->production_time.month, p->production_time.day, 
   		p->state_over, p->state_warning);
   	num++;
   	p = p->next;
   }
   fclose(fp);
   printf("保存结束,共保存了%d项商品数据!\n", num);
}

//销毁商品链表释放内存
void DestroyGoodsLine(Goods* head)
{
     
   Goods* p, * q1, * q2;
   p = head;
   q1 = p->next;
   if (q1 == NULL) return;
   q2 = q1->next;
   while (q1->next)
   {
     
   	free(q1);
   	q1 = q2;
   	q2 = q2->next;
   }
}

//超市仓库管理系统的设计与实现.c
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <malloc.h>
#include "date.h"
#include "admin.h"
#include "goods.h"
#pragma warning(disable:6031)
#pragma warning(disable:4996)


//主函数
int main()
{
     
   int choice;
   int admin, password;
   FILE* fp1;
   FILE* fp2;

   fp1 = fopen("goods.txt", "r");
   if (fp1 == NULL) {
      printf("商品文件打开错误!\n"); exit(0); }
   fp2 = fopen("admin.txt", "r");
   if (fp2 == NULL) {
      printf("管理员文件打开错误!\n"); exit(0); }

   Goods* goods_head = NULL;
   Admin* admin_head = NULL;
   Admin* p = NULL;
   goods_head = Read_GoodsFile(fp1);							//从数据文件中逐行读取商品信息生成商品链表
   admin_head = Read_AdminFile(fp2);						    //从数据文件中逐行读取管理员信息生成管理员链表

   if (fclose(fp1)) {
      printf("关闭商品文件错误!\n"); exit(0); }		 //关闭商品文件
   if (fclose(fp2)) {
      printf("关闭管理员文件错误!\n"); exit(0); }      //关闭管理员文件

   while (1)
   {
     
   	system("cls");													//清屏
   	printf("********************欢迎使用超市仓库管理系统********************\n");
   	printf("\n");
   	printf("                  1-超级管理员 2-管理员 0-退出                  \n");
   	printf("请选择您的身份:");
   	scanf("%d", &choice);
   	if (choice == 0) break;
   	getchar();//读回车符
   	switch (choice)
   	{
     
   	case 1: {
     
   		system("cls");
   		printf("********************欢迎使用超市仓库管理系统********************\n");
   		printf("\n");
   		printf("请输入账号:\n");
   		scanf("%d", &admin);
   		printf("请输入密码:\n");
   		scanf("%d", &password);
   		if (admin == Super_Admin && password == Super_Password)
   		{
     
   			system("cls");
   			printf("********************欢迎使用超市仓库管理系统********************\n");
   			printf("\n");
   			printf("*1-添加管理员           2-删除管理员           0-退出          *\n");
   			scanf("%d", &choice);
   			if (choice == 0) break;
   			switch (choice)                                                                 
   			{
     
   			case 1:admin_head = InsertAdmin(admin_head); system("pause"); break;
   			case 2:printf("请输入要删除的管理员的账号:\n"); scanf("%d", &admin); admin_head = DeleteAdmin(admin_head, admin); system("pause"); break;
   			}
   		}
   		else if (admin != Super_Admin) {
     
   			printf("账号输入错误!\n");
   			system("pause");
   			break;
   		}
   		else if (password != Super_Password) {
     
   			printf("密码输入错误!\n");
   			system("pause");
   			break;
   		}
   		else
   			break;

   	}break;
   	case 2: {
     
   		system("cls");
   		printf("********************欢迎使用超市仓库管理系统********************\n");
   		printf("\n");
   		printf("请输入账号:\n");
   		scanf("%d", &admin);
   		printf("请输入密码:\n");
   		scanf("%d", &password);
   		p = admin_head;
   		choice = 1;
   		while ((p->admin != admin) && (p->password != password)) {
      p = p->next; }
   		if (p->admin != admin)
   			printf("账号输入错误!\n");
   		else if (p->password != password)
   			printf("密码输入错误!\n");
   		else while(choice){
     
   			system("cls");
   			printf("********************欢迎使用超市仓库管理系统********************\n");
   			printf("\n");
   			printf("*                                                              *\n");
   			printf("*       1-入库            2-出库            3-查询             *\n");
   			printf("*                                                              *\n");
   			printf("*       4-排序            5-修改            6-统计             *\n");
   			printf("*                                                              *\n");
   			printf("*                         0-退出                               *\n");
   			printf("请输入你的选择:\n");
   			scanf("%d", &choice);
   			if (choice == 0) break;
   			switch (choice)
   			{
     
   			case 1: {
     
   				system("cls");
   				printf("********************欢迎使用超市仓库管理系统********************\n");
   				printf("\n");
   				goods_head = In_WareHouse(goods_head); 
   				printf("商品入库完成!\n");
   			}system("pause"); break;
   			case 2: {
     
   				system("cls");
   				printf("********************欢迎使用超市仓库管理系统********************\n");
   				printf("\n");
   				goods_head = Out_WareHouse(goods_head); 
   				printf("商品出库完成!\n");
   			}system("pause"); break;
   			case 3: {
     
   				system("cls");
   				printf("********************欢迎使用超市仓库管理系统********************\n");
   				printf("\n");
   				printf("*1-查询商品库存     2-查询当天入/出库商品      3-查询商品保质期*\n");
   				printf("*                                                              *\n");
   				printf("*                          0-退出                              *\n");
   				scanf("%d", &choice);
   				if (choice == 0) break;
   				switch (choice) 
   				{
     
   				case 1: {
     
   					system("cls");
   					printf("********************欢迎使用超市仓库管理系统********************\n");
   					printf("\n");
   					goods_head = GoodsStock_Query(goods_head);
   				}system("pause"); break;
   				case 2: {
     
   					system("cls");
   					printf("********************欢迎使用超市仓库管理系统********************\n");
   					printf("\n");
   					goods_head = GoodsInOut_Query(goods_head);
   				}system("pause"); break;
   				case 3: {
     
   					system("cls");
   					printf("********************欢迎使用超市仓库管理系统********************\n");
   					printf("\n");
   					GoodsQualityTime(goods_head);
   				}system("pause"); break;
   				default: printf("输入错误!!!\n\n"); break;
   				}
   			}break;
   			case 4: {
     
   				system("cls");
   				printf("********************欢迎使用超市仓库管理系统********************\n");
   				printf("\n");
   				Goods_Sort(goods_head);
   				printf("排序完成!\n");
   				GoodsShow(goods_head);
   			}system("pause"); break;
   			case 5: {
     
   				system("cls");
   				printf("********************欢迎使用超市仓库管理系统********************\n");
   				printf("\n");
   				goods_head = Goods_Edit(goods_head);
   			}system("pause"); break;
   			case 6: {
     
   				system("cls");
   				printf("********************欢迎使用超市仓库管理系统********************\n");
   				printf("\n");
   				GoodsShow(goods_head);
   			}system("pause"); break;
   			default: printf("输入错误!!!\n\n"); break;
   			}

   		}
   	}system("pause"); break;
   	default: printf("输入错误!!!\n\n"); break;
   	}

   }

   Save_To_GoodsFile(goods_head);//将商品数据写入商品文件
   DestroyGoodsLine(goods_head);//销毁商品单链表释放内存

   Save_To_AdminFile(admin_head);//将管理员写入管理员文件
   DestroyAdminLine(admin_head);//销毁管理员单链表释放内存

   printf("\n\n******************欢迎再次使用超市仓库管理系统******************\n\n");


   return 0;
}
//admin.txt
222 456
333 789
444 444
//goods.txt
1001 a1 468 200 60 15 30 438 2020 9 1 0 0
1002 a2 123 100 90 16 31 92 2020 9 24 0 0
1003 a3 92 38 30 17 32 60 2020 8 29 1 1
1004 a4 234 48 35 18 33 201 2020 7 26 1 0
1005 a5 789 28 60 19 34 755 2020 1 1 1 0
1006 a6 72 88 60 20 35 37 2020 3 1 1 1
1007 a7 48 8 20 21 36 12 2020 3 2 1 1
1008 a8 101 59 30 22 37 64 2020 5 1 1 0
1009 a9 213 1999 180 23 38 175 2020 6 1 0 0
1010 a10 512 654 30 24 39 473 2020 6 2 1 0
1011 b1 12 5 5 25 20 -8 2020 9 30 1 1
1012 b2 22 7 5 26 41 -19 2020 10 1 1 1
1013 b3 158 6 10 27 42 116 2020 9 1 1 0
1014 b4 352 8 8 28 43 309 2020 9 20 1 0
1015 b5 258 9 30 29 44 214 2020 9 30 0 0
1016 b6 147 10 60 30 45 102 2020 9 28 0 0
1017 b7 369 11 30 31 46 323 2020 9 27 0 0
1018 b8 357 12 30 32 47 310 2020 9 27 0 0
1019 b9 162 13 30 33 48 114 2020 9 27 0 0
1020 b10 263 14 30 34 49 214 2020 9 27 1 0
1021 c1 111 56 35 35 50 61 2020 9 1 1 0
1022 c2 222 23 60 36 51 171 2020 9 1 0 0
1023 c3 333 45 60 37 52 281 2020 9 1 0 0
//stockin.txt
1001 15 2020 10 1 
1002 16 2020 10 1
1003 17 2020 10 1
1004 18 2020 10 1
1005 19 2020 10 1
1006 20 2020 10 1
1007 21 2020 10 1
1008 22 2020 10 1
1009 23 2020 10 1
1010 24 2020 10 1
1011 25 2020 10 2
1012 26 2020 10 2
1013 27 2020 10 2
1014 28 2020 10 2
1015 29 2020 10 2
1016 30 2020 10 2
1017 31 2020 10 2
1018 32 2020 10 2
1019 33 2020 10 2
1020 34 2020 10 2
1021 35 2020 10 3
1022 36 2020 10 3
1023 37 2020 10 3
//stockout.txt
1001 30 2020 10 25
1002 31 2020 10 26
1003 32 2020 10 15
1004 33 2020 10 17
1005 34 2020 10 13
1006 35 2020 10 14
1007 36 2020 10 15
1008 37 2020 10 16
1009 38 2020 10 17
1010 39 2020 10 18
1011 20 2020 10 19
1012 41 2020 10 8
1013 42 2020 10 21
1014 43 2020 10 22
1015 44 2020 10 23
1016 45 2020 10 24
1017 46 2020 10 25
1018 47 2020 10 26
1019 48 2020 10 27
1020 49 2020 10 28
1021 50 2020 10 29
1022 51 2020 10 30
1023 52 2020 10 31

你可能感兴趣的:(C语言,数据结构,链表,c语言,数据结构,链表)