新建 文本文档.txt
来自「这个程序是用C语言实现的。我使用了单向链表来实现对药品的增加. 删除等操作. 我」· 文本 代码 · 共 516 行
TXT
516 行
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <time.h>
#include <conio.h>
enum sign {
ALL, ONE, MONTH = 3, DAY = 6, SET = 10};
#define WRITE(W, L, FW) (fwrite((W), 1, sizeof(L), (FW)))
#define READ(R, N, FR) (fread((R), 1, sizeof(N), (FR)))
#define STRCMP(NAME, STR) strcmp((char *)GetStdin(NAME, "%s", STR), "0")
#define ERROR() cputs("操作失败!\n\n");
#define FIRST "请输入药品名称或编号:\n"
#define SECOND "请输入药品名称或编号(按0结束):\n"
#define MENU "************************\n"\
"1 - 增加药品\n"\
"2 - 删除药品\n"\
"3 - 查找药品\n"\
"4 - 更新药品\n"\
"5 - 结帐\n"\
"6 - 显示药品列表\n"\
"7 - 显示销售记录\n"\
"8 - 修改密码\n"\
"0 - 退出\n"\
"************************\n"\
"请选择:"
#define UPDATEMENU "1 - 更新药品名称.\n"\
"2 - 更新药品产地.\n"\
"3 - 更新药品价格.\n"\
"4 - 更新药品数量.\n"\
"0 - 退出.\n"
#define RECORDMENU "1 - 显示日销售记录.\n2 - 显示月销售记录.\n0 - 退出.\n"
struct list_tag {//药品信息
char number[21];//药品编号
char name[21];//名称
char product[16];//产地
float price;//价格
int amount;//库存
struct list_tag *next;
};
struct record_tag {//销售记录
time_t times;//时间
char num[21];//编号
char name[21];//名称
float rate;//价格
int scalar;//卖出数量
double subtotal;//小计
};
void *GetStdin(const char *numstr, char *control, void *t);
int PassWord(const char *sec, const char *pass);
int CompareTime(time_t ftime, time_t stime, int clen);
double PrintRecord(FILE *fpr, time_t compare, int len);
FILE *FileOpen(const char *first);
FILE *FUpdate(FILE *puf, const char *upname, time_t up);
struct list_tag *Insert(struct list_tag *fst, const struct list_tag *dst);
struct list_tag *Delete(struct list_tag *fd, const char *destr);
struct list_tag *SearchList(const struct list_tag *serlist, const char *serstr);
struct list_tag *GetValue(struct list_tag *ref);
struct list_tag *FileLoad(FILE *fin, struct list_tag *start);
void PayList(FILE *fs, FILE *frew, const struct list_tag *palist);
void PayPrint(FILE *fstr, time_t set, float practice);
void FileSave(FILE *fPtr, const struct list_tag *f);
void ListOut(const struct list_tag *pst, int sparam);
void GetWord(FILE *p, char *word);
void Revision(FILE *rew);
void Get(const char *str, char *getstr);
void UpdateRecord(FILE *fup, const struct record_tag *strup);
void RecordCopy(struct record_tag *recp, const struct list_tag *relist, time_t time, int i);
void UpdateFile(FILE *puf, const char *upstr, int uplen);
void ListOperator(struct list_tag *oplist, int od, void (*Operator)(struct list_tag *, int));
void UpdateList(struct list_tag *ullist, int ud);
main()
{
FILE *file = FileOpen("C:\\WINDOWS\\medicine.rec");
FILE *fout, *paword = FileOpen("C:\\WINDOWS\\pass.rec");
FILE *fdata = FileOpen("C:\\WINDOWS\\data.rec");
struct list_tag *list = NULL;
struct list_tag red;
int choice, c;
time_t t;
char string[30], s[10];
GetWord(paword, s);//验证密码
list = FileLoad(file, list);//载入文件信息
while (*(int *)GetStdin(MENU, "%d", &choice)) {
fdata = FUpdate(fdata, "C:\\WINDOWS\\date.rec", time(NULL));
switch (choice) {
case 1:
while (STRCMP(SECOND, red.number)) {
if (! SearchList(list, red.name)) {
list = Insert(list, GetValue(&red));//增加药品
cputs("药品添加成功!\n\n");
}
else
cputs("药品已存在!\n\n");
}
break;
case 2:
while (STRCMP(SECOND, string)) {
if (SearchList(list, string)) {
list = Delete(list, string);
cputs("药品删除成功!\n\n");
}
else
cputs("药品不存在!\n\n");
}
break;
case 3:
ListOperator(list, ONE, ListOut);
break;
case 4:
ListOperator(list, ONE, UpdateList);
break;
case 5:
fout = tmpfile();//打开临时文件
PayList(fout, fdata, list);//显示清单
rmtmp();//关闭临时文件
break;
case 6:
ListOut(list, ALL);//显示药品信息
break;
case 7:
while (*(int *)GetStdin(RECORDMENU, "%d", &c)) {
time(&t);
if (c == 1)
PrintRecord(fdata, t, DAY);
else if (c == 2)
PrintRecord(fdata, t, MONTH);
}
break;
case 8:
do
cputs("您确定要更改密码吗(Y or N) ?\n");
while ((c=getch()) != 'y' && c!='n');
system("cls");//清屏
if (c == 'y') {
do
Get("\n请输入你的原始密码:\n", string);
while (strcmp(s, string));
Revision(paword);
}
break;
}
}
FileSave(file, list);//保存药品信息
fcloseall();//关闭所有文件
return 0;
}
void *GetStdin(const char *numstr, char *control, void *ret)
{
cputs(numstr);
while (! scanf(control, ret)) {
fflush(stdin);
system("cls");//清屏
cputs(numstr);
}
system("cls");//清屏
return ret;
}
//向链表插入一个元素
struct list_tag *Insert(struct list_tag *fst, const struct list_tag *dst)
{
struct list_tag *newPtr;
if (!fst || strcmp(fst->number, dst->number) > 0) {//按编号的大小插入药品
if (newPtr = (struct list_tag *) malloc(sizeof (struct list_tag))) {
*newPtr = *dst;
newPtr->next = fst;
}
return newPtr;
}
else if (strcmp(fst->number, dst->number) < 0)
fst->next = Insert(fst->next, dst);
return fst;
}
//删除链表的一个元素
struct list_tag *Delete(struct list_tag *fd, const char *destr)
{
struct list_tag *templist = fd;
if (fd && !(strcmp(fd->name, destr) && strcmp(fd->number, destr))) {
fd = fd->next;
free(templist);
}
else if (fd)
fd->next = Delete(fd->next, destr);
return fd;
}
//在链表中查找药品的编号或名称
struct list_tag *SearchList(const struct list_tag *serlist, const char *serstr)
{
while (serlist && strcmp(serlist->name, serstr) && strcmp(serlist->number, serstr))
serlist = serlist->next;
return (struct list_tag *)serlist;
}
//读取一个链表值
struct list_tag *GetValue(struct list_tag *ref)
{
GetStdin("请输入药品名称:\n", "%s", ref->name);//得到药品名称
GetStdin("请输入药品价格:\n", "%f", &ref->price);//得到药品价格
GetStdin("请输入药品产地:\n", "%s", ref->product);//得到药品产地
GetStdin("请输入药品数量:\n", "%d", &ref->amount);//得到药品数量
return ref;
}
//计算药品总价格
void PayList(FILE *fs, FILE *frew, const struct list_tag *palist)
{
int i;
float fact;
double total = 0.00;
char str[30];
struct list_tag *plst;
struct record_tag ptmp;
rewind(frew);
while (STRCMP(SECOND, str))
if (plst = SearchList(palist, str)) {
GetStdin("请输入买出的药品数量\n", "%d", &i);
plst->amount -= i;
total += plst->price * i;
RecordCopy(&ptmp, plst, time(NULL), i);
UpdateRecord(frew, &ptmp);//更新销售记录
UpdateRecord(fs, &ptmp);
}
else
ERROR();
if (total) {
printf("应付款: %.2f元\n请输入实际付款额:\n", total);
GetStdin("", "%f", &fact);//得到实际付款
PayPrint(fs, time(NULL), fact);
}
}
void ListOut(const struct list_tag *pst, int sparam)
//显示整个链表
{
printf ("%-20s%-20s%-15s%-15s%-15s\n", "药品编号", "名称", "价格", "产地", "库存");
for (; pst!=NULL; pst=pst->next) {
printf ("%-20s%-20s%-15.2f%-15s%-15d\n",
pst->number, pst->name, pst->price, pst->product, pst->amount);
if (sparam)
return ;
}
}
void PayPrint(FILE *fstr, time_t set, float practice)
//显示购买药品的清单
{
double coin;
printf ("时间: %s\n", ctime(&set));
coin = PrintRecord(fstr, set, SET);
printf ("\n应付款: %.2f\n实付款: %.2f\n找 零: %.2f\n", coin, practice, practice - coin);
}
void FileSave(FILE *fPtr, const struct list_tag *f)
//保存文件
{
rewind(fPtr);
for (; f; f=f->next)
WRITE(f, struct list_tag, fPtr);
}
int PassWord(const char *sec, const char *pass)
{
char b[10];
Get(sec, b);
return strcmp(pass, b);
}
//输入密码
void GetWord(FILE *p, char *word)
{
int i = 0;
if (! fread(word, 7, 1, p)) {//如果文件是空的
strcpy(word, "000000");//设置初始密码
fwrite(word, 7, 1, p);//写入初始密码
}
while (PassWord("请输入您的密码:\n", word)) {
if (++i == 3)//如果密码三次输入错误,则退出系统
exit(0);
cputs("\n对不起. 您输入的密码有误, 请验证后再重新输入!\n");
}
system("cls");
}
//修改密码
void Revision(FILE *rew)
{
char str[10], s[10];
Get("\n请输入你的新密码:\n", str);
Get("\n请再输一次:\n", s);
if (! strcmp(str, s)) {
rewind(rew);
fwrite(s, 7, 1, rew);//写入新的密码
}
cputs(strcmp(str, s) ? "\n错误!\n": "\n修改成功!\n");
}
//获取密码
void Get(const char *str, char *getstr)
{
int i = 0;
while (*str)
putchar(*str++);
while (++i <= 6) {//输入一个六位数的密码
*getstr++ = getch();
putchar('*');
}
*getstr = '\0';
}
//读取文件中的数据
struct list_tag *FileLoad(FILE *fin, struct list_tag *start)
{
struct list_tag read;
while (READ(&read, struct list_tag, fin))/*读取文件信息*/
start = Insert(start, &read);
return start;
}
//如果文件存在,就以读的方式打开它。否则,以写的方式打开它
FILE *FileOpen(const char *first)
{
FILE *fo = fopen(first, "ab+");
int n = feof(fo);
fclose(fo);
if (! (fo = fopen(first, n ? "wb+" : "rb+"))) {
cputs("不能打开文件.\n");
exit(0);
}
return fo;
}
//设置一个销售记录结构的值
void RecordCopy(struct record_tag *recp, const struct list_tag *relist, time_t time, int i)
{
recp->times = time;
strcpy(recp->num, relist->number);
strcpy(recp->name, relist->name);
recp->rate = relist->price;
recp->scalar = i;
recp->subtotal = relist->price * i;
}
//更新销售记录
void UpdateRecord(FILE *fup, const struct record_tag *strup)
{
struct record_tag atmp;
int n;
rewind(fup);
while ((n=READ(&atmp, struct record_tag, fup)) && strcmp(atmp.name, strup->name))
;
if (n) {//如果该记录已经存在,更新相应的数量和销售额
atmp.scalar += strup->scalar;
atmp.subtotal = strup->rate * atmp.scalar;
fseek(fup, - (long)sizeof(struct record_tag), SEEK_CUR);
WRITE(&atmp, struct record_tag, fup);
}
else //否则,在文件的结尾写入该记录
WRITE(strup, struct record_tag, fup);
}
double PrintRecord(FILE *fpr, time_t compare, int len)
//显示销售记录
{
struct record_tag rtmp;
double money = 0;
time_t steam = time(NULL);
rewind(fpr);
printf ("%-20s%-20s%-15s%-15s%-20s\n", "药品编号", "名称", "单价", "卖出数量", "销售额");
while (READ(&rtmp, struct record_tag, fpr))
if (! CompareTime(rtmp.times, steam, len)) {
printf ("%-20s%-20s%-15.2f%-15d%-20.2f\n", rtmp.num, rtmp.name, rtmp.rate,
rtmp.scalar, rtmp.subtotal);
money += rtmp.subtotal;//计算总销售额
}
return money;
}
//如果销售记录的日期不符合,则废弃旧的销售记录
FILE *FUpdate(FILE *puf, const char *upname, time_t up)
{
struct record_tag utmp;
rewind(puf);
if (READ(&utmp, struct record_tag, puf) && CompareTime(utmp.times, up, MONTH)) {
fclose(puf);
puf = fopen(upname, "wb+");
}
return puf;
}
//比较两个时间, len有两个可供选择的值:MONTH(比较月份), DAY(比较日期).
//如过两个时间相等, 返回0. 否则返回一个真值.
int CompareTime(time_t ftime, time_t stime, int clen)
{
char fstr[26] ;
char rstr[26];
strcpy(fstr, ctime(&ftime));
strcpy(rstr, ctime(&stime));
return strncmp(fstr + 4, rstr + 4, clen) || strcmp(fstr + 20, rstr + 20);
}
void ListOperator(struct list_tag *oplist, int od, void(*Operator)(struct list_tag *, int))
{
char opstr[50];
while (strcmp((char *)GetStdin(SECOND, "%s", opstr), "0"))
if (SearchList(oplist, opstr))
(*Operator)(oplist, od);
else
ERROR();
}
void UpdateList(struct list_tag *ullist, int ud)
{
int ulc;
GetStdin(UPDATEMENU, "%d", &ulc);
switch (ulc) {
case 1:
GetStdin("请输入药品的新名称:\n", "%s", ullist->name);
break;
case 2:
GetStdin("请输入药品的新产地:\n", "%s", ullist->product);
break;
case 3:
GetStdin("请输入药品的新价格\n", "%f", &ullist->price);
break;
case 4:
ullist->amount += *(int *)GetStdin("请输入购进的药品数量\n", "%d", &ulc);
break;
}
ListOut(ullist, ud);
}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?