#include<stdio.h>
#include<stdlib.h>
#include<windows.h>
#include<string.h>
/*没错,用多个宏定义简化代码,这可是最新操作!*/
/*惊喜不惊喜,意外不意外?*/
#define C card_imf
#define S struct
#define SIZE sizeof(S C)
#define T count
#define H head
#define I int
#define P printf
#define N scanf
S C
{
long number;
char name[20];
double money;
I lost;
S C *next;
};
I user_choice;
FILE *fp;
S C *Creat_new();//初次运行程序时新建链表
void Open_File(char *openmode);//打开文件
void Close_File();//关闭文件
void Build_File();//初次运行程序时新建数据文件
void Use_Card(S C *H,I T);//消费
void Insert_Card(S C *H,I T);//插入新饭卡信息
void Charge_Money(S C *H,I T);//充值
void Delete_Card(S C *H,I T);//注销饭卡
void Lost_Card(S C *H,I T);//挂失饭卡
void Search_Card(S C *H,I T);//查找指定饭卡数据
void Start_Card(S C *H,I T);//初次运行程序时输入的初始数据
void Sort_Card(S C *H,I T);//对饭卡数据进行排序
void Print_Card(S C *H);//遍历饭卡文件
I Input_Choice();//输入的选项编号
I Check_Card(S C *H,I T,I num);//检查某编号的饭卡是否存在
I main()
{
long num;
while((user_choice=Input_Choice())!=0)
{
I T=1;
S C *H,*p;
if(user_choice==1)
Build_File();
H=Creat_new();
if(H==NULL)//由于初次执行程序时会出现群龙无首的错误,所以把「第一次接收数据」和「第N次接收数据」分类讨论(我没别的意思,别想歪了)
{
switch(user_choice)
{
case 2:
case 3:
case 4:
Start_Card(H,T);
break;
case 5:
case 6:
case 7:
P("请输入饭卡号:");
N("%d",&num);
P("饭卡不存在!\n");
system("pause");
system("cls");
break;
default:
system("cls");
break;
}
}
else
{
p=H;
while(p->next!=NULL)
{
p=p->next;
T++;
}
switch(user_choice)
{
case 2:
Use_Card(H,T);
break;
case 3:
Charge_Money(H,T);
break;
case 4:
Insert_Card(H,T);
break;
case 5:
Delete_Card(H,T);
break;
case 6:
Lost_Card(H,T);
break;
case 7:
Search_Card(H,T);
break;
case 8:
Sort_Card(H,T);
break;
case 9:
Print_Card(H);
break;
default:
system("cls");
break;
}
}
}
P("感谢使用本软件。已正常退出,按任意键结束。\n");
return 0;
}
I Input_Choice()
{
I i,j,k;
for(i=1; i<=14; i++)
{
for(j=1; j<=20; j++)
P(" ");
if(i==1||i==3||i==14)
{
for(k=1; k<=30; k++)
P("-");
}
else if(i==2)
P("☆ 请输入选项编号(0-9): ☆");
else if(i==4)
P("★ 1--建立饭卡文件 ★");
else if(i==5)
P("★ 2--消费 ★");
else if(i==6)
P("★ 3--充值 ★");
else if(i==7)
P("★ 4--添加新饭卡 ★");
else if(i==8)
P("★ 5--注销旧饭卡 ★");
else if(i==9)
P("★ 6--设置与解除挂失 ★");
else if(i==10)
P("★ 7--查询饭卡信息 ★");
else if(i==11)
P("★ 8--排序饭卡信息 ★");
else if(i==12)
P("★ 9--遍历饭卡信息 ★");
else if(i==13)
P("★ 0--退出系统 ★");
P("\n");
}
P("\n请输入选项编号:");
N("%d",&user_choice);
return user_choice;
}
void Close_File()
{
if(fclose(fp))
{
P("Can not close the file!\n");
exit(0);
}
}
void Open_File(char *openmode)
{
if((fp=fopen("card.dat",openmode))==NULL)
{
P("File open error!\n");
exit(0);
}
}
S C *Creat_new()
{
Open_File("r");
S C data;
S C *H,*tail,*p;
H=tail=NULL;
while(fscanf(fp,"%ld%s%lf%d",&data.number,data.name,&data.money,&data.lost)!=EOF)
{
p=(S C *)malloc(SIZE);
p->number=data.number;
strcpy(p->name,data.name);
p->money=data.money;
p->lost=data.lost;
p->next=NULL;
if(H==NULL)
H=p;
else
tail->next=p;
tail=p;
}
Close_File();
return H;
}
void fp_file(S C *H,I flag)//把内存链表中储存的文本内容写回到存储介质中的文件
{
S C *p;
Open_File("w");
p=H;
while(flag>0)
{
fprintf(fp,"%ld\t%s\t%f\t%d\n",p->number,p->name,p->money,p->lost);
p=p->next;
flag--;
}
Close_File();
}
void Build_File()
{
Open_File("w");
P("文件建立成功!\n");
Close_File();
system("pause");
system("cls");
}
void Use_Card(S C *H,I T)
{
long num;
I flag=T;
double balance,charge;
S C *p;
p=H;
P("请输入饭卡号:");
N("%ld",&num);
if(Check_Card(H,T,num)==-1)
P("饭卡不存在!\n");
else
{
P("请输入饭费:");
N("%lf",&charge);
while(T>0)//遍历饭卡,找到使用者的卡并进行扣费
{
if(p->number==num)
{
if(p->money<5)
P("余额不足,请充值!\n");
else if(p->lost==1)
P("本卡已冻结!\n");
else
{
balance=p->money-charge;
if(balance<0) P("余额不足,请充值!\n");
else
{
P("买饭前余额:%.2f\n",p->money);
p->money=balance;
P("买饭后余额:%.2f\n",p->money);
}
}
break;
}
p=p->next;
T--;
}
fp_file(H,flag);
}
system("pause");
system("cls");
}
void Charge_Money(S C *H,I T)
{
long num;
I flag=T;
double charge;
S C *p;
p=H;
P("请输入饭卡号:");
N("%ld",&num);
if(Check_Card(H,T,num)==-1) P("饭卡不存在!\n");
else
{
P("请输入充值额:");
N("%lf",&charge);
while(T>0)
{
if(p->number==num)
{
if(p->lost==1) P("本卡已冻结!\n");
else
{
P("充值前余额:%.2f\n",p->money);
p->money=p->money+charge;
P("充值后余额:%.2f\n",p->money);
}
break;
}
p=p->next;
T--;
}
fp_file(H,flag);
}
system("pause");
system("cls");
}
void Insert_Card(S C *H,I T)
{
char a[5];
S C *p1,*p2,new_data;
p2=H;
strcpy(a,"是");
while(strcmp(a,"是")==0)
{
P("请输入饭卡号:");
N("%ld",&new_data.number);
if(Check_Card(H,T,new_data.number)==1)
P("饭卡已存在!\n");
else
{
P("请输入姓名:");
N("%s",new_data.name);
P("请输入金额:");
N("%lf",&new_data.money);
new_data.lost=0;
p1=(S C *)malloc(SIZE);
p1->number=new_data.number;
strcpy(p1->name,new_data.name);
p1->money=new_data.money;
p1->lost=new_data.lost;
while(p2->next!=NULL)
p2=p2->next;
p2->next=p1;
p2=p1;
p2->next=NULL;
T++;
fp_file(H,T);
}
P("是否继续添加饭卡号:");
getchar();
gets(a);
}
system("pause");
system("cls");
}
void Start_Card(S C *H,I T)
{
S C *p;
S C new_data;
P("请输入饭卡号:");
N("%ld",&new_data.number);
P("请输入姓名:");
N("%s",new_data.name);
P("请输入金额:");
N("%lf",&new_data.money);
new_data.lost=0;
p=(S C *)malloc(SIZE);
p->number=new_data.number;
strcpy(p->name,new_data.name);
p->money=new_data.money;
p->lost=new_data.lost;
H=p;
H->next==NULL;
fp_file(H,T);
system("pause");
system("cls");
}
void Delete_Card(S C *H,I T)
{
long num;
I flag=T;
P("请输入饭卡号:");
N("%ld",&num);
S C *p1,*p2,*p;
p2=p1=H;
if(Check_Card(H,T,num)==-1)
P("饭卡不存在!\n");
else
{
Open_File("w");
while(T>0)
{
if(p1->number==num)
{
if(p1==H)
{
H=p1->next;
}
else
{
p2->next=p1->next;
}
free(p1);
goto loop;
}
p2=p1;
p1=p1->next;
T--;
}
loop:p=H;
while(flag>1)
{
fprintf(fp,"%ld\t%s\t%f\t%d\n",p->number,p->name,p->money,p->lost);
p=p->next;
flag--;
}
Close_File();
P("旧饭卡注销成功!\n");
}
system("pause");
system("cls");
}
void Lost_Card(S C *H,I T)
{
I flag=T;
char a[5];
long num;
S C *p;
p=H;
P("请输入饭卡号:");
N("%ld",&num);
if(Check_Card(H,T,num)==-1)
P("饭卡不存在!\n");
else
{
while(T>0)
{
if(p->number==num)
{
if(p->lost==0)
{
P("当前饭卡未挂失!是否挂失:");
N("%s",a);
if(strcmp(a,"是")==0)
p->lost=1;
}
else if(p->lost==1)
{
P("当前饭卡已挂失!是否解除挂失:");
N("%s",a);
if(strcmp(a,"是")==0)
p->lost=0;
}
}
p=p->next;
T--;
}
fp_file(H,flag);
P("操作成功!\n");
}
system("pause");
system("cls");
}
void Search_Card(S C *H,I T)
{
long num;
S C *p;
p=H;
P("请输入饭卡号:");
N("%ld",&num);
if(Check_Card(H,T,num)==-1)
P("饭卡不存在!\n");
else
{
P("饭卡号\t姓名\t金额\t是否挂失\n");
while(T>0)
{
if(p->number==num)
{
if(p->lost==0)
P("%ld\t%s\t%.2f\t%s\n",p->number,p->name,p->money,"否");
else
P("%ld\t%s\t%.2f\t%s\n",p->number,p->name,p->money,"是");
break;
}
p=p->next;
T--;
}
}
system("pause");
system("cls");
}
I Check_Card(S C *H,I T,I num)
{
S C *p;
p=H;
while(T>0)
{
if(p->number==num)
break;
T--;
p=p->next;
}
if(T==0)
return -1;
else
return 1;
}
void Sort_Card(S C *H,I T)//通过两个指针就能实现链表的冒泡排序
{
S C *p1,*p2,temp;
I i,j,k;
p1=p2=H;
P("1.由大到小排列\n2.由小到大排列 \n请选择排列方式:\n");
while(i!=1&&i!=2)
{
N("%d",&i);
if(i==1)
{
for(j=1; j<T; j++)
{
p2=p2->next;
for(k=0; k<(T-j); k++)
{
if((p1->number)<(p2->number))
{
temp=*p1;
temp.next=p2->next;
*p1=*p2;
*p2=temp;
p1->next=p2;
}
p2=p2->next;
p1=p1->next;
}
p2=p1=H;
}
}
else if(i==2)
{
for(j=1; j<T; j++)
{
p2=p2->next;
for(k=0; k<(T-j); k++)
{
if((p1->number)>(p2->number))
{
temp=*p1;
temp.next=p2->next;
*p1=*p2;
*p2=temp;
p1->next=p2;
}
p2=p2->next;
p1=p1->next;
}
p2=p1=H;
}
}
else
P("请输入正确的选项编号!\n");
}
P("已按照您的选项进行排列!\n");
fp_file(H,T);
system("pause");
system("cls");
}
void Print_Card(S C *H)
{
S C *p;
P("学生饭卡信息如下:\n");
P("饭卡号\t姓名\t金额\t是否挂失\n");
for(p=H;p!=NULL;p=p->next)
{
if(p->lost==0)
P("%ld\t%s\t%.2f\t%s\n",p->number,p->name,p->money,"否");
else
P("%ld\t%s\t%.2f\t%s\n",p->number,p->name,p->money,"是");
}
system("pause");
system("cls");
}