**
@库存管理系统-中山大学管理学院C语言程序设计课程大作业
**
受疫情的影响,2020年初我们通过网课的形式学习了C语言基础这门课程。而期末的考核也以大作业的形式进行。在这次大作业考核中,我们被要求编写一个库存管理系统,其中需要实现的基础功能是:管理商品的出库和入库、将商品信息通过程序写入文件中存储并且在下次打开文档的时候读入库存数据、查找商品功能、展示库存功能;除了基础功能之外,图形界面、库存预警功能、美观的操作界面是本次作业的加分项。
而下面展示的是我的作业内容,在此说明,本人非计算机专业且C语言水平大概处于班上中游,所以本人水平不代表学院水平。若有不当之处,欢迎交流。
***视频简介部分:***
本次编程是在64位windows系统下进行,IDE是Visual Studio 2017
应考核要求录制了视频一个,已上传B站,链接如下:
https://www.bilibili.com/video/BV17v411q7t6/
***技术报告部分:***
同时我还做了一份技术报告,里面讲述了我的程序功能和一些思路概
要以及各函数对应实现的功能,因为有六页PDF所以就和源代码一起
放百度网盘分享好了。链接如下:
https://pan.baidu.com/s/1iKArY5R1rAEsMRt05pCn7Q
提取码:hi32
***源代码部分:***
#define _CRT_SECURE_NO_WARNINGS//Visual C++里面为了运行scanf等相对于最新标准来说较古老的函数
//仓库管理系统**2020年6月**程序设计课程大作业
#include<stdio.h>
#include<stdlib.h>
#include<Windows.h>
#include<string.h>
void openscene(); //主菜单界面函数
void readin(); //读入文件中的库存信息
void putout(); //将库存信息写入文件
void stockin(); //商品入库函数
void stockout(); //商品出库函数
void display(); //展示商品函数
void search(); //查找商品函数
void changewarningvalue(); //更改预设商品库存预警值函数
void thetail(); //各功能与主菜单连接函数,用于返回主菜单界面
void checkscanf(int ,int* );//检查用户对每一个scanf的数据类型输入是否正确
//定义商品种类、库存预警值、scanf输入测试值
int amountoftype, warningvalue, check=0;
//定义商品种类的结构变量
struct sku {
int number;//商品编号
char name[10];//商品名称
int amount;//库存数量
}stock[100];//仓库可储存100种不同商品
int main()
{
openscene();//引出主菜单
return 0;
}
void openscene(void)//开机初始画面
{
int inter;//功能选择变量
printf("*********************************************\n");
printf("* 欢迎来到星火库存管理系统V2.0 *\n");
printf("* *\n");
printf("* 功能列表: *\n");
printf("* *\n");
printf("* 1.入库 2.出库 *\n");
printf("* *\n");
printf("* 3.展示所有商品 4.查找商品 *\n");
printf("* *\n");
printf("* 5.更改库存预警值 6.退出 *\n");
printf("* *\n");
printf("*********************************************\n");
printf("请选择功能序号:");
check=scanf("%d", &inter);
checkscanf(check,&inter);//检查scanf是否正确录入数据
system("CLS");//进入功能界面前清理显示内容,保持界面整洁
switch (inter) //选择不同功能
{
case 1://入库功能
readin();
stockin();
putout();
thetail();
break;
case 2://出库功能
readin();
stockout();
putout();
thetail();
break;
case 3://展示全部商品功能
readin();
display();
thetail();
break;
case 4://搜索商品功能
readin();
search();
thetail();
break;
case 5://更改库存预警值
readin();
changewarningvalue();
putout();
thetail();
break;
case 6://退出程序
exit(0);//在每一个程序结束之后都会回到主菜单函数的情况下,这是程序的唯一出口
break;
default://当输入错误时,重新回到开机页面
printf("\a\a");//出现错误的提示音
printf("你输入的选项有误,请重试,");
system("pause");
openscene();
break;
}
}
void readin()//读入库存文件
{
FILE*fp = fopen("stock.txt", "r");//打开文件,只读
int i = 0;
if (fp)
{
fscanf(fp, "%d", &warningvalue);//先读入设置的库存预警值
while (1)//读入货品信息并计数
{
fscanf(fp, "%s%d%d", &stock[i].name, &stock[i].number, &stock[i].amount);
if (feof(fp)) break;//当文件读入到文件末尾时,停止读入
i++;
}
amountoftype = i;//确认商品个数
fclose(fp);
}
else printf("\033[47;31m(如果是第一次使用程序可以忽略本行)打开文件失败\n\033[0m");//防止打开文件失败
}
void putout()//更改后的商品信息输出到文件
{
FILE*fp = fopen("stock.txt", "w");//打开文件并清除原有内容
if (fp)
{
fprintf(fp, "%-10d\n", warningvalue);//先写入库存预警值
for (int x = 0;x < amountoftype;x++)//逐个写入各商品信息
{
if (stock[x].amount != -1)//当出库函数中货物刚刚好消耗尽时,设置数量为-1,不写入文件
{
fprintf(fp, "%-10s", stock[x].name);
fprintf(fp, "%-10d", stock[x].number);
fprintf(fp, "%-10d\n", stock[x].amount);
}
}
fclose(fp);
}
else printf("\033[47;31m打开文件失败\033[0m");//防止打开文件失败
}
void stockout(void)//出库函数
{
int findnumber, deductnumber, ne = 1;//定义要出货的商品编号、要出库的数量、是否找到商品的指示值
printf("请输入商品编号:");
check=scanf("%d", &findnumber);
checkscanf(check, &findnumber); printf("\n\n");//检查scanf、换行使得视觉美观
for (int x = 0;x < amountoftype;x++)
{
if (findnumber == stock[x].number)
{
ne = 0;//找到货物则ne=0
printf("货物名称为%s,请输入商品出货数目:",stock[x].name);
check=scanf("%d", &deductnumber);
checkscanf(check, &findnumber);printf("\n\n");
if (stock[x].amount == deductnumber)
{
printf("\033[47;31m货物刚好全部耗尽\033[0m\n\n");//\033[47;31m....\033[0m改变字体颜色
stock[x].amount = -1;//货物耗尽时定义数量为-1
}
else if (stock[x].amount < deductnumber)
{
printf("\033[47;31m需求量超过了库存!请求非法,此次出货失败\033[0m\n\n");
printf("\a\a");//当出库数量大于货物本身数量时,红色文字提示加系统鸣响声音预警
}
else
{
stock[x].amount -= deductnumber;
printf("出货成功!\n\n");
}
if (stock[x].amount < warningvalue && stock[x].amount>0)//出库后剩余库存小于预警值时预警
{
printf("\033[47;31m出货后该商品库存小于预警值%d,请注意\n\n\033[0m", warningvalue);
}
}
}
if (ne == 1)//没有找到相应的商品编号
{
printf("\a\a");//出现错误的提示音
printf("这是一个仓库没有的商品!请重试\n\n");
stockout();//重新执行出库函数
}
printf("是否继续出货?继续请按1,否则按2: ");
int yesorno;//判断是否继续出货的指示值
check=scanf("%d", &yesorno);
checkscanf(check, &yesorno); printf("\n\n");//检查scanf
if (yesorno == 1)
{
system("CLS");
stockout();//继续出货则再运行一次出货函数
}
}
void stockin(void)//入货函数
{
int findnumber, addnumber, ne = 1;//定义要入货的商品编号、要出库的数量、是否找到商品的指示值
printf("请输入商品编号(新增商品也输入将会拥有的编号即可):");
check=scanf("%d", &findnumber);
checkscanf(check, &findnumber); printf("\n");//检查scanf
for (int x = 0;x < amountoftype;x++)//寻找商品
{
if (findnumber == stock[x].number)
{
ne = 0;//指示变量,为0时表示该商品为仓库已有种类
printf("该商品名称是%s,请输入商品入库数目",stock->name);
check=scanf("%d", &addnumber);
checkscanf(check, &addnumber); printf("\n");//检查scanf
stock[x].amount += addnumber;//执行入库,增加库存数量
printf("入库成功!\n");
break;
}
}
if (ne == 1)//在库存中找不到该商品
{
printf("这是一个仓库没有的商品\n\n");
stock[amountoftype].number = findnumber;//将货品信息写入库存商品数组中下一个空位
printf("请为这个商品输入名称:");
scanf("%s", &stock[amountoftype].name);printf("\n");//货品名称
printf("请输入商品入库数目:");
check=scanf("%d", &addnumber);//数量
checkscanf(check, &addnumber); printf("\n\n");//检查scanf
stock[amountoftype].amount = addnumber;
amountoftype++;//增加现存货品种类数
printf("入库成功!\n");
}
printf("是否继续入库?继续请按1,否则按2或者其它键: ");
int yesorno;//判断是否继续入库的指示值
check=scanf("%d", &yesorno);
checkscanf(check, &yesorno); printf("\n\n");//检查scanf
if (yesorno == 1)
{
system("CLS");
stockin();//继续出货则再运行一次入库函数
}
}
void display()//展示库存商品函数
{
int yesorno;
printf("是否启动预警系统?(启动后库存数低于预警值的货品将被标红)启动请按1,否则按2或者其他键:");
check = scanf("%d", &yesorno);
checkscanf(check, &yesorno); printf("\n\n");//检查scanf
switch (yesorno)
{
case 1://使用库存预警功能
printf("货品全部信息如下:\n\n");
printf("货品编号 货品名称 数量 \n");
for (int x = 0;x < amountoftype;x++)
{
if (stock[x].amount > warningvalue)//库存充足时,绿色字体显示
printf("\033[47;32m%-12d%-22s%-8d\033[0m\n\n", stock[x].number, stock[x].name, stock[x].amount);
else//库存不足时,红色字体显示
printf("\033[47;31m%-12d%-22s%-8d\033[0m\n\n", stock[x].number, stock[x].name, stock[x].amount);
}
break;
default:
printf("货品全部信息如下:\n\n");
printf("货品编号 货品名称 数量 \n");
for (int x = 0;x < amountoftype;x++)//商品信息普通显示
{
printf("\033[47;32m%-12d%-22s%-8d\033[0m\n\n", stock[x].number, stock[x].name, stock[x].amount);
}
break;
}
}
void search()//查找商品功能:可选择用名称搜索还是编号
{
char searchname[10];//待搜商品名字
int searchnumber, inter;//待搜商品编号,选择指示变量
int findornot = 1;//判断商品是否被搜索到
printf("欢迎使用查找功能\n");
printf("编号查找请按1,名称查找请按2或任意数字键:\n");
check=scanf("%d", &inter);
checkscanf(check, &inter); printf("\n\n");//检查scanf
if (inter == 1)//编号搜索
{
printf("请输入要查找的商品编号:\n");
check=scanf("%d", &searchnumber);
checkscanf(check, &searchnumber); printf("\n\n");//检查scanf
for (int x = 0;x < amountoftype;x++)
{
if (searchnumber == stock[x].number)
{
findornot = 0;
printf("货品信息如下:\n\n");
printf("货品编号 货品名称 数量 \n\n");
printf("\033[47;32m%-12d%-22s%-8d\033[0m\n\n", stock[x].number, stock[x].name, stock[x].amount);
break;
}
}
}
else//名称搜索
{
printf("请输入要查找的商品名称:\n");
scanf("%s", &searchname);
for (int x = 0;x < amountoftype;x++)
{
if (strcmp(searchname, stock[x].name) == 0)
{
findornot = 0;
printf("货品信息如下:\n");
printf("货品编号 货品名称 数量 \n");
printf("\033[47;32m%-12d%-22s%-8d\033[0m\n", stock[x].number, stock[x].name, stock[x].amount);
break;
}
}
}
if (findornot)//没有找到时
{
printf("\a\a");//出现错误的提示音
printf("\033[47;31m所找的货物不存在,请重试\033[0m\n");
system("pause");
system("CLS");
search();
}
//选择是否继续查找
int yesorno;
printf("是否继续查找,是请按1,否请按2或者其它键:");
check=scanf("%d", &yesorno);
checkscanf(check, &yesorno); printf("\n\n");//检查scanf
if (yesorno == 1)
{
system("CLS");
search();//继续搜索
}
}
//更改预警值,库存预警值初始为10
void changewarningvalue()
{
printf("当前的预警值为%d,请输入新的预警值:",warningvalue);
check=scanf("%d", &warningvalue);
checkscanf(check, &warningvalue); printf("\n\n");//检查scanf
printf("更改完成");
}
//返回主菜单函数
void thetail()
{
printf("即将返回主菜单,");
system("pause");//停留一下,增强交互感
system("CLS");//清理显示界面,保持屏幕整洁
openscene();
}
void checkscanf(int check,int* inter)//用于检查程序中多次出现的scanf是否正确读入int类型数据
{
int r=1,newnumber;//指示值和错误读入的数据的替代值
while (check != 1) //scanf会返回正确读入的数据个数
{
r = 0;
while (getchar() != '\n'); //当scanf没有遇到正确的数据类型时,它不会读入数据,数据留在缓冲区
//这个循环把这些数据包括回车键清理掉
printf("\a\a");//出现错误的提示音
printf("输入的数据类型不是数字类型,请再次输入:");
check = scanf("%d", &newnumber);
}
if(r==0) *inter = newnumber;//将正确的值赋予收集数据的变量
}