哎呀呀,我整晚都在挑战自己的链表管理极限,奋斗了一晚,才做了个
半成品,当然勉强地把一个二级菜单做了出来了(还得感谢吹版那个菜单框架)
用链表实现的,实现了添加,删除蔬菜的功能,加入购买列表和结余功能暂时还没有完善,有时间再更~
说实话,你那个问题似乎太多了,修改要花很大功夫而且我也不能保证我能改好,还是把这个半成品拿出来看看~
半成品的代码已经够长的了~这个我没写太多注释,这个是给大家一起看的~重点是如何做菜单嵌套(我只是做了一个二级目录,在此框架上还可以多添加几层目录)~
程序代码:
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#define CR (Vegetable*)malloc(sizeof(Vegetable))
typedef struct Vegetable
{
int num;//选择数量
int pay;
char name[10];
char price[10];
struct Vegetable *next;
struct Vegetable *list_next;//这个是清单链表指针~
}Vegetable;
Vegetable *head=NULL;
Vegetable *head_list=NULL;
typedef void (*COM[8])();//定义新类型变量
int n=0;//节点
int L=0;//加入列表数
int END=0;//全局变量,返回菜单用~
int PAY=0;
void menu();//显示菜单
void print();//输出蔬菜数据
void creat();//创建\\添加数据到末尾
void del();//删除数据蔬菜数据
void choose();//选择蔬菜
void change();//交易
int judge();//判断是否是空表
int judge_input(Vegetable *p,char s[]);//判断输入格式
int judge_input2();
void judge_find(Vegetable *p);//这个是用来删除数据时变动购买列表清单指针的(该功能还没完善,释放指针会影响购买列表而出错)~
void menu_list();//显示列表清单数据
void creat_list();//创建列表清单
void del_list();//删除列表清单
void print_list();
void menu_back();//返回上一个目录
void quit();//退出程序
void menu_main(COM command[],int n);
COM command[2] =
{
{quit,creat,print,choose,change,del,NULL,menu},
{menu_back,creat_list,del_list,print_list,NULL,NULL,NULL,menu_list}
};
int main()
{
menu_main(command,sizeof(command[0])/sizeof(void *));
return 0;
}
void menu_main(COM command[2],int n)
{
char cmd;
(*command[0][7])();
while (1)
{
while ((cmd=getch())&&cmd>='0'&&cmd-'0'<n)
{
system("cls");
fflush(stdin);
if (*command[0][cmd-'0']!=NULL)
(*command[0][cmd-'0'])();
fflush(stdin);
system("cls");
if (END==0)
(*command[0][7])();
else
{
END=0;
return;
}
}
fflush(stdin);
}
}
void menu()
{
printf("1:创建\\追加数据到末尾\n");
printf("2:输出数据\n");
printf("3选择蔬菜\n");
printf("4:交易\n");
printf("5:删除蔬菜数据\n");
printf("0:退出\n");
}
void creat()
{
Vegetable *p=head;
char s[100]={0};
while (head&&p->next)//把指针移向尾部
p=p->next;
printf("输入蔬菜名和价格(中间用空格隔开)\n");
printf("输入0退出处理\n");
while (1)
{
printf("%d--",n+1);
scanf("%[^\n]%*c",s);
if (judge_input(p,s))//判断输入
return;
n++;
if (n==1)
{
p=head=CR;
p->list_next=NULL;
}
else
{
p=p->next=CR;
p->list_next=NULL;
}
sscanf(s,"%s%[^\n]",p->name,p->price);
}
}
void print()
{
int i=1;
Vegetable *p=head;
if (judge())
return;
while (p)
{
printf("%d:-%s %s元\\斤\n",i++,p->name,p->price);
p=p->next;
}
printf("请按任意键继续\n");
getch();
}
void del()
{
int num=0;
Vegetable *p=head;
Vegetable *p2=NULL;
if (judge())
return;
printf("请选择需要删除蔬菜的编号\n(现在还有%d个蔬菜,输入0退出操作,输入-1打印蔬菜列表)\n",n);
while (1)
{
p=head;
p2=NULL;
if ((num=judge_input2())&&num==-1)
return;
printf("%d号蔬菜已经被删除\n",num);
printf("请按任意键继续\n");
getch();
if (num==1)
{
judge_find(head);
head=head->next;
free(p);
n--;
if (judge())
return;
printf("请选择需要删除蔬菜的编号\n(现在还有%d个蔬菜,输入0退出操作,输入-1打印蔬菜列表)\n",n);
continue;
}
while (num-->2)
p=p->next;
p2=p->next;
judge_find(p2);
p->next=p->next->next;
n--;
free(p2);
if (judge())
return;
printf("请选择需要删除蔬菜的编号(现在还有%d个蔬菜,输入0退出操作,输入-1打印蔬菜列表)\n",n);
}
}
void choose()
{
if (judge())
return ;
menu_main(command+1,sizeof(command[0])/sizeof(void *));
}
void change()
{}
int judge()
{
if (head==NULL)
{
printf("请先初始化数据\n");
printf("请按任意键继续\n");
getch();
}
system("cls");
return head==NULL;
}
int judge_input(Vegetable *p,char s[])//判断输入合法性,比较麻烦,可以优化~
{
if (strlen(s)==0&&head)
{
p->next=NULL;
system("cls");
return 1;
}
else if (strlen(s)==0)
{
system("cls");
return 1;
}
if ((s[0]=='0'||s[0]==' '||(char *)memchr(s,' ',sizeof(s))==NULL||s[strlen(s)-1]==' ')&&head)
{
p->next=NULL;
system("cls");
return 1;
}
else if ((s[0]=='0'||s[0]==' '||(char *)memchr(s,' ',sizeof(s))==NULL||s[strlen(s)-1]==' ')&&head==NULL)
{
system("cls");
return 1;
}
return 0;
}
void menu_list()
{
printf("1:选择购买的蔬菜编号\n");
printf("2:删减购买列表\n");
printf("3:打印购买列表\n");
printf("4:显示所需要的金钱\n");
printf("0:返回上一个目录\n");
}
void creat_list()//这个功能还没完善~
{
int num=0;
int count=0;
int sum=0;
Vegetable *p=head;
Vegetable *pl=head_list;
system("cls");
print();
print_list();
printf("\n");
printf("请输入选择的蔬菜编号\n");
if (num=judge_input2()&&num==-1)
return;
while (head_list&&pl->list_next) //把指针移向尾部
pl=pl->list_next;
while (num-->1)
p=p->next;
if (p->list_next!=NULL)
{
printf("该蔬菜你也选择,按1:查看\\更改购买数量,按2:取消本次操作\n");//这里还没有完善
getch();
return;
}
if (head_list==NULL)
{
pl=head_list=p;
pl->list_next=NULL;
}
else
{
pl->list_next=p;
p->list_next=NULL;//这个还没有完善
}
printf("请输入购买数量(按0则数量为0,,取消操作)\n");
scanf("%d",&count);
sum=atoi(p->price);
p->num=sum;
sum*=count;
p->pay=sum;
PAY+=sum;
L++;
}
void judge_find(Vegetable *p)
{
}
void del_list()
{}
void print_list()
{
int i=1;
Vegetable *p=head_list;
if (L==0)
{
printf("\n现在你还没有进行选购蔬菜\n");
printf("请按任意键继续\n");
getch();
return ;
}
while (p)
{
printf("%d:-%s %s元\\斤\n",i++,p->name,p->price);
p=p->list_next;
}
printf("请按任意键继续\n");
getch();
}
void menu_back()
{
END=1;
}
int judge_input2()
{
int num=0;
while (scanf("%d",&num)!=1||num<0||num>n)
{
if (num==-1)
{
print();
printf("请选择需要执行操作蔬菜的编号\n(现在还有%d个蔬菜,输入0退出操作,输入-1打印蔬菜列表)\n",n);
}
else
printf("输入数据有误,请重新输入\n");
fflush(stdin);
}
system("cls");
if (num==0)
{
system("cls");
return -1;
}
return num;
}
void quit()
{
exit(0);
}
//删除链表要变动两个指针,构思虽好,但到头来费的功夫反而还多,倒不如另外开一个链表来存放购买清单比较理想(这个我还要再改动一下)~
[此贴子已经被作者于2016-12-23 07:40编辑过]