新建 文本文档.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 + -
显示快捷键?