# 基于C语言实现的仓库管理系统
# 1 题目要求
该系统用于实现仓库管理,系统应支持入库、出库、库存查询以及打印。用户可自定库存警戒值,库存低于警戒值时以红字显示。仓库信息需要用文件存储。
# 2 需求分析
根据题目要求,由于货品信息存放在文件中,所以应该提供文件的读入、输出等操作;在程序中要浏览货品信息,应提供显示、查找、排序等操作;实现货物入库功能,要提供结构体的输入操作;实现统计功能,要提供相应的统计操作;实现修改功能,要提供修改操作;另外,还要提供键盘式菜单实现功能选择。
# 3 总体设计
根据上面的需求分析,可以将该系统的系统的设计分为大模块,即入库模块、出库模块、查询模块、排序模块、修改模块和统计模块等。
![](http://www.write-bug.com/myres/static/uploads/2021/10/19/3b8ee7574c0b2ffcdb4879b41f7c0ce9.writebug)
# 4 详细设计
## 4.1 主函数
![](http://www.write-bug.com/myres/static/uploads/2021/10/19/77aa0dce20c1c24df2c000d0fda60ad6.writebug)
```c++
# include<stdio.h>
# include<windows.h>
# include<string.h>
# include<conio.h>
void main()
{
int sele;
Re_file(); //读取货品信息
sele=1;
while(sele)
{
system("cls");
printf("\n\n");
printf("*********************************************\n");
printf("* *\n");
printf("* 1.入库 2.出库 *\n");
printf("* *\n");
printf("* 3.查询 4.排序 *\n");
printf("* *\n");
printf("* 5.修改 6.统计 *\n");
printf("* *\n");
printf("* 7.退出 *\n");
printf("* *\n");
printf("*********************************************\n");
printf("请选择功能序号:");
scanf("%d",&sele);
switch(sele)
{
case 1:Stock_in();Display();break;
case 2:Stock_out();Display();break;
case 3:Query();break;
case 4:Sort();Display();break;
case 5:Modify();Display();break;
case 6:Statistics();break;
case 7:exit(0);sele=0;break;
}
printf("\n\n按任意键继续...\n");
getch();
}
Wr_file();
}
```
## 4.2 各功能模块设计
### 4.2.1 数据读入模块
单独看各组数据信息,货品名称是字符串,可以采用字符型数组;其他数据均可用整数存放。数据信息存放在文件中,一条记录对应一种货品的信息,既符合习惯也方便信息管理。把一种货品的相关信息作为结构体成员,如果要存放若干种货品的信息就要用结构体数组。
```c++
typedef struct
{
int num; //货品编号
char name[20]; //货品名称
int stock; //原始库存
int in; //入库数目
int out; //出库数目
int amount; //最终库存
int warning_value; //警戒值
int state; //库存状态(是否低于警戒值)
}goods;
goods s[M]; //用于存放货品信息
goods r[M]; //用于存放入库货品信息
goods t[M]; //用于存放出库货品信息
```
s[M]、r[M]、t[M]的M为货品种类数,程序中采用宏定义的方式,可以随时在源程序宏定义中修改。本程序中宏定义为:#define M 50。
```c++
void Re_file() //读入原始库存文件
{
FILE*fp;
N=0;
fp=fopen("goods.txt","r");
while(fscanf(fp,"%d%s%d%d%d%d%d",&s[N].num,&s[N].name,&s[N].stock,&s[N].in,&s[N].out,&s[N].amount,&s[N].warning_value)!=EOF)
N++;
fclose(fp);
P=N;
}
```
### 4.2.2 入库模块
![](http://www.write-bug.com/myres/static/uploads/2021/10/19/20648fbcf30ef017accf53f7b5406f4b.writebug)
该模块的功能是根据题目要求读入货品的入库数据。注意在主函数中已经读入了原始数据。
```c++
void Stock_in() //读入入库文件
{
FILE*fp;
int i,j;
N=0;
fp=fopen("stockin.txt","r");
while(fscanf(fp,"%d%d",&r[N].num,&r[N].in)!=EOF)
N++;
fclose(fp);
for(i=0;i<P;i++)
{
for(j=0;j<N;j++)
{
if(r[i].num==s[j].num)
s[j].in=r[j].in;
}
}
for(i=0;i<P;i++)
s[i].amount=s[i].stock+s[i].in;
}
```
### 4.2.3 出库模块
该模块的功能是根据题目要求读入货品的出库数据。注意在主函数中已经读入了原始数据。
```c++
void Stock_out() //读入出库文件
{
FILE*fp;
int i,j;
N=0;
fp=fopen("stockout.txt","r");
while(fscanf(fp,"%d%d",&t[N].num,&t[N].out)!=EOF)
N++;
fclose(fp);
for(i=0;i<P;i++)
{
for(j=0;j<N;j++)
{
if(t[i].num==s[j].num)
s[j].out=t[j].out;
}
}
for(i=0;i<P;i++)
s[i].amount=s[i].stock+s[i].in-s[i].out;
}
```
### 4.2.4 浏览模块
![](http://www.write-bug.com/myres/static/uploads/2021/10/19/9892ddb29734aadccfae3dd925e297c8.writebug)
该模块的功能是显示所有货品的记录信息。根据货品库存数目是否低于警戒值,分别按红字显示和白字显示。采用SetConsoleTextAttribute函数改变输出字体颜色。
```c++
void Display() //显示库存情况
{
int i,j;
system("cls");
Estimate();
printf("货品编号 货品名称 原始库存 入库数目 出库数目 最终库存 警戒值\n");
for(i=0,j=1;i<P;i++,j++)
{
if(s[i].state==1) //库存值小于警戒值红字显示
{
HANDLE handle = GetStdHandle(STD_OUTPUT_HANDLE);
SetConsoleTextAttribute(handle, FOREGROUND_INTENSITY | FOREGROUND_RED);
printf("%-9d %-10s%-10d%-10d%-10d%-10d%-10d\n", s[i].num, s[i].name, s[i].stock, s[i].in, s[i].out, s[i].amount, s[i].warning_value);
if(j%10==0&&j!=P) //控制每次显示十行
{
printf("按任意键继续...");
getch();
puts("\n");
SetConsoleTextAttribute(handle, FOREGROUND_INTENSITY | FOREGROUND_RED| FOREGROUND_GREEN | FOREGROUND_BLUE);
printf("货品编号 货品名称 原始库存 入库数目 出库数目 最终库存 警戒值\n");
}
}
else if(s[i].state==0) //库存值不小于警戒值白字显示
{
HANDLE handle = GetStdHandle(STD_OUTPUT_HANDLE);
SetConsoleTextAttribute(handle, FOREGROUND_INTENSITY | FOREGROUND_RED| FOREGROUND_GREEN | FOREGROUND_BLUE);
printf("%-9d %-10s%-10d%-10d%-10d%-10d%-10d\n", s[i].num, s[i].name, s[i].stock, s[i].in, s[i].out, s[i].amount, s[i].warning_value);
if(j%10==0&&j<P)
{
HANDLE handle = GetStdHandle(STD_OUTPUT_HANDLE);
SetConsoleTextAttribute(handle, FOREGROUND_INTENSITY | FOREGROUND_RED| FOREGROUND_GREEN | FOREGROUND_BLUE);
printf("按任意键继续...");
getch();
puts("\n");
printf("货品编号 货品名称 原始库存 入库数目 出库数目 最终库存 警戒值\n");
}
}
}
}
```
### 4.4.5 判断模块
该模块用于判断货品库存数目是否小于警戒值并记录,多次在其他被模块调用。
```c++
// 判断库存值是否小于警戒值
void Estimate()
{
int i;
for(i=0;i<P;i++)
{
if(s[i].amount>=s[i].warning_value)
s[i].state=0;
else if(s[i].amount<s[i].warning_value)
s[i].state=1;
}
}
```
### 4.4.6 查询模块
![](http://www.write-bug.com/myres/static/uploads/2021/10/19/12bea1ec0638308feefdec683f2ac698.writebug)
该模块的功能是根据输入的货品名称或货号查找对应的记录,找到以后,显示货品记录。同时,库存数目小于警戒值以红字显示。
```c++
// 查询货品
void Query()
{
int k,m,i,j=-1;
char n[20];
system("cls");
printf("\n\n");
printf("*********************************************\n");
printf("* *\n");
printf("* *\n");
printf("* *\n");
printf("* 1.货品编