本文小编为大家详细介绍“C语言如何实现点菜系统”,内容详细,步骤清晰,细节处理妥当,希望这篇“C语言如何实现点菜系统”文章能帮助大家解决疑惑,下面跟着小编的思路慢慢深入,一起来学习新知识吧。
一、main.c
#include<stdio.h>#include<string.h>#include<stdlib.h>#include<windows.h>//Sleep#include"user.h"#include"loginWin.h"//登录界面使用#include"Admin.h"//管理员界面使用#include"Manager.h"//经理界面使用#include"Waiter.h"//服务员界面使用#include"guanRen.h"//人员管理窗口使用#include"xinZeng.h"//新增用户窗口使用#include"daYin.h"//打印查询窗口使用#include"xiuGai.h"//修改密码窗口使用 int count =3; //初始化两个用户 全局变量 //初始化用户结构体数组 做全局变量 其他.c中extern外部引用 USER_T userArr[10]={ {1001,"admin","123456",1},//0 ADMIN {1002,"manager","123456",2},//1 MANAGER {1003,"waiter","123456",3}//2 WAITER }; void proRun(){ int(*win_funs[30])()={loginInit,adminInit,managerInit,waiterInit,guanrenInit,xinZengInit ,daYinInit,xiuGaiInit}; int winIndex = 0; //0-loginInit 1-adminInit 2-managerInit 3-waiterInit while(1) { Sleep(1500); system("cls"); winIndex=win_funs[winIndex](); }} int main(){ proRun(); }
二、Ctool.h
#ifndef CTOOL_H#define CTOOL_H#define KEY_UP 72#define KEY_DOWN 80#define KEY_LEFT 75#define KEY_RIGHT 77#define KEY_ESC 27#define KEY_ENTER 13 void paintWindow(int startX,int startY,int width,int height);//打印窗口 void gotoxy(int x,int y);//形参 光标定位 void glb_string(int maxLen,int inputType,int ips,char str[]); int getkey(); //打印用户信息表格void daYinBiao(int x,int y,int lie,int hang); #endif
三、Ctool.c
#include "Ctool.h"#include <windows.h>//gotoxy#include<stdio.h>#include<conio.h> void gotoxy(int x,int y)//形参{ HANDLE hOut; COORD pos= {x,y}; // 光标的起始位(第1列,第3行) 0是第1列 2是第3行 hOut = GetStdHandle(STD_OUTPUT_HANDLE); SetConsoleCursorPosition(hOut, pos); //printf("定位光标位置搜索(%d,%d)\n",pos.X,pos.Y);} void paintWindow(int startX,int startY,int width,int height) { int i=0; //打印顶部 //光标定位 找规律 ┗ ┛ ┏ ┓ ┃ ━ //顶部 y不变 x 在变 (x-x+w) gotoxy(startX,startY); printf("┏"); for(i=0;i<width-2;i++) //控制循环次数width-2次 { printf("━ "); } printf("┓"); //左边 x不变 y在变 (y到y+height) for(i=1;i<=height-1;i++) { gotoxy(startX,startY+i); printf("┃"); } //右边 x不变 =startx+width-1 y在变 y 到 y+height for(i=1;i<=height-1;i++) { gotoxy(startX+width*2-3,startY+i); printf("┃"); } //底部 x在变化 y不变 (x到x+width) ━ gotoxy(startX,startY+height-1); printf("┗"); for(i=0;i<width-2;i++) { printf("━ "); } printf("┛"); gotoxy(startX,startX+height); } void glb_string(int maxLen,int inputType,int ips,char str[]){ char ch=0; int i=0; while(1) { ch=getch(); if(ch=='\r'&&i>0)//换行结束输入 { break; } switch(inputType) { case 0: if(ch>='0'&&ch<='9'&&i<maxLen) { if(ips==0) { putch('*'); } else{ putch(ch); } str[i++]=ch; } break; case 1: if(i<maxLen&&(ch>='a'&&ch<='z')||(ch>='A'&&ch<='Z')) { if(ips==0) { putch('*'); } else{ putch(ch); } str[i++]=ch; } break; case 2: if(i<maxLen&&(ch>='a'&&ch<='z')||(ch>='A'&&ch<='Z')||(ch>='0'&&ch<='9')) { if(ips==0) { putch('*'); } else{ putch(ch); } str[i++]=ch; } break; default: break; } } } int getkey(){ char key=0; key=getch(); if(key==-32)//方向按键 第一个值都是32 { key=getch(); switch(key){ case 72: return KEY_UP; case 80: return KEY_DOWN; case 75: return KEY_LEFT; case 77: return KEY_RIGHT; } } else if(key==13) { return KEY_ENTER; } else if(key==27) { return KEY_ESC; } return key; } void daYinBiao(int x,int y,int lie,int hang) { //lie --表格列数-- 3--7 int i,j,m,z=0; int count=0; gotoxy(x,y); for(i=0;i<2*hang+1;i++) { if(i==0)//第一行 { printf("┌ "); //第一列 for(j=0;j<lie-1;j++)//2 - n-1列---┬ { for(m=0;m<7;m++) { printf("━ "); } printf("┬ ");//每个单元格之间的分割 } for(m=0;m<7;m++) { printf("━ "); } printf("┐"); } if(i>0&&i<2*hang)//1-6行 { if(i%2==1) //数据行 { gotoxy(x,i+y); printf("┃"); for(j=0;j<lie;j++) //0-3 { for(m=0;m<7;m++) { printf(" "); } printf(" ┃"); } } else //单元格边界 { gotoxy(x,i+y); printf("├ "); for(j=0;j<lie-1;j++) { for(m=0;m<7;m++) { printf("━ "); } printf("┼ "); } for(m=0;m<7;m++) { printf("━ "); } printf("┤"); } } //最后一行 // ┌ ━ ┬ ┐┃ ┼ ├ ┤ └ ┘ ┴ if(i==2*hang) { gotoxy(x,y+2*hang); printf("└ "); for(j=0;j<lie-1;j++)//2 - n-1列---┴ { for(m=0;m<7;m++) { printf("━ "); } printf("┴ ");//每个单元格之间的分割 } for(m=0;m<7;m++) { printf("━ "); } printf("┘"); } }}
四、Cwindow.h
#ifndef CWINDOW_H#define CWINDOW_H//描述窗口相关的#define LABEL 1 //控件使用宏定义 标签文本#define EDIT 2 // 编辑框#define BUTTON 3// 按钮 //标签结构体的声明typedef struct label_t{ int startx; //标签文本所放位置 int starty; int width;//标签文本自身宽高 int height; char content[20];//标签文本中输入对应的内容 字符数组}; //编辑框结构体的声明typedef struct edit_t{ int startx;//编辑框所放位置 int starty; int width;//编辑框自身宽高 int height; char content[20];//编辑框中输入的内容 字符数组的使用 int inputType;//输入类型 0-数字 1-字母 2-数字+字母 int ips;//显示类型 0-密文 1-明文 int maxLen; //最大长度 }; //按钮结构体的声明typedef struct button_t{ int startx;//按钮所放位置 int starty; int width;//按钮自身宽高 int height; char content[20];//按钮中输入的内容 }; //以编辑框为标准统一管控(编辑框要求最多) //控件结构体的声明--编辑框 标签 按钮typedef struct control_t{ int startx;//控件所放位置 int starty; int width;//控件自身宽高 int height; int maxLen;//最大长度 int inputType;//输入类型 0-数字 1-字母 2-数字+字母 int ips;//显示类型 0-密文 1-明文 int ctrlType; //控件类型 1-label 2-edit 3-button 区分控件的使用 char content[20];//控件中输入的内容 }CONTROL_T;//typedef重命名 //窗口结构体的声明 控件是要放入窗口当中的typedef struct win_t{ int startx;//窗口所放位置 int starty; int width;//窗口对应宽高 int height; CONTROL_T ctrlArr[20];//存放控件结构体数组 窗口中有多个控件 int ctrlCount; //记录控件总个数 初始化为0 用于添加控件函数中 int foucsIndex; //winRun在按钮回车时记录当前控件的下标}WIN_T; //添加控件 void addControl(参数1:控件结构体 参数2:控件结构体数组 参数3:控件个数);//把控件放进控件结构体数组中 ctrlCount控件个数 预留出下一个控件结构体下标//int addControl(CONTROL_T ctrl,CONTROL_T ctrlArr[20] , int ctrlCount);//添加控件到对应窗口中void addControl(CONTROL_T ctrl,CONTROL_T ctrlArr[20] , int *ctrlCount); //窗口显示函数可以绘制整个窗口以及每一个控件 而paintWindow只能画大框 不能显示里面的内容 void showWindow(WIN_T win); void winRun(WIN_T *win); void editKeyListen(CONTROL_T ctrl,char ch,char content[]); #endif
五、Cwindow.c
#include "Cwindow.h"#include "Ctool.h"#include<conio.h>// getch()#include<string.h>//strlen //添加控件 void addControl(参数1:控件结构体 参数2:控件结构体数组 参数3:控件个数);//把控件放进控件结构体数组中 ctrlCount控件个数 预留出下一个控件结构体下标void addControl(CONTROL_T ctrl,CONTROL_T ctrlArr[20] , int *ctrlCount){ ctrlArr[(*ctrlCount)++]=ctrl;//按地址传递} //窗口显示函数 绘制整个窗口以及每一个控件void showWindow(WIN_T win){ int i=0; //首先显示大框 paintWindow(win.startx,win.starty,win.width,win.height);//结构体变量名.属性 //显示每一个控件 for(i=0;i<win.ctrlCount;i++)//遍历ctrlArr[]数组 长度ctrlCount一个一个获取 控件在窗口里 { //类型 label edit button //如果是label 直接显示内容即可 //如果是edit 画框(paintWindow) 显示内容 //如果是button 画框 显示内容 if(win.ctrlArr[i].ctrlType==LABEL) { gotoxy(win.ctrlArr[i].startx,win.ctrlArr[i].starty);//光标定位放入内容 puts(win.ctrlArr[i].content); } else { //画编辑框 按钮框(小框) 避免小框和放入的内容镶嵌 paintWindow(win.ctrlArr[i].startx-2,win.ctrlArr[i].starty-1,win.ctrlArr[i].width,win.ctrlArr[i].height); gotoxy(win.ctrlArr[i].startx,win.ctrlArr[i].starty);//光标定位放入内容 puts(win.ctrlArr[i].content); } } gotoxy(0,29);//优化显示} void winRun(WIN_T *win){ int i=0,key=0; for(i=0;i<win->ctrlCount;i++) { if(win->ctrlArr[i].ctrlType==EDIT||win->ctrlArr[i].ctrlType==BUTTON) { gotoxy(win->ctrlArr[i].startx,win->ctrlArr[i].starty); break; } } while(1) { key=getkey(); switch(key){ case KEY_DOWN://向下按键 查找下一个编辑框 按钮 i++;//按键数组下标越界 if(i==win->ctrlCount) { i=0;//为了避免下标越界 从头开始对控件结构体数组找编辑框 按钮 } for(;i<win->ctrlCount;i++) { if(win->ctrlArr[i].ctrlType==EDIT||win->ctrlArr[i].ctrlType==BUTTON)//如果找到编辑框 按钮 { gotoxy(win->ctrlArr[i].startx,win->ctrlArr[i].starty);//光标目标定位 break;//停止 } } break; case KEY_UP: i--; if(i==-1) //从后往前找 数组起始0 i--为-1 数组下标由大到小 (控件数组下标0位置) { i=win->ctrlCount-1; //控件个数(控件结构体数组下标最大)-1 (控件数组下标ctrlCount位置) } for(;i>0;i--) { if(win->ctrlArr[i].ctrlType==EDIT||win->ctrlArr[i].ctrlType==BUTTON)//如果找到编辑框 按钮 { gotoxy(win->ctrlArr[i].startx,win->ctrlArr[i].starty);//光标目标定位 break;//停止 } if(i==0) //第一个 若第一个不是编辑框 按钮 { i=win->ctrlCount; //就从最后一个往前查找 for循环中有i--,不用再-1 } } break; case KEY_ENTER: if(win->ctrlArr[i].ctrlType==BUTTON) { win->foucsIndex=i; return ;//获取winRun中输入的编辑框的值 } break; default: //其他字符(不是按键)并且当前控件是编辑框 if(win->ctrlArr[i].ctrlType==EDIT) { editKeyListen(win->ctrlArr[i],key,win->ctrlArr[i].content); } break; } }} void editKeyListen(CONTROL_T ctrl,char ch,char content[]){ int i=strlen(content);//从字符串原来的长度开始存储 switch(ctrl.inputType) { case 0: //数字 if(ch>='0'&&ch<='9'&&i<ctrl.maxLen) { if(ctrl.ips==0) { putch('*'); } else{ putch(ch); } content[i++]=ch; } break; case 1: if(i<ctrl.maxLen&&(ch>='a'&&ch<='z')||(ch>='A'&&ch<='Z')) { if(ctrl.ips==0) { putch('*'); } else{ putch(ch); } content[i++]=ch; } break; case 2: if(i<ctrl.maxLen&&(ch>='a'&&ch<='z')||(ch>='A'&&ch<='Z')||(ch>='0'&&ch<='9')) { if(ctrl.ips==0) { putch('*'); } else{ putch(ch); } content[i++]=ch; } break; default: break; }}
六、user.h
#ifndef USER_H#define USER_H#define ADMIN 1#define MANAGER 2#define WAITER 3 //用户结构体声明typedef struct user_t{ int ID; char name[20]; char pwd[20]; int role; //数字表示角色 1是admin 2是 manager 3 是waiter}USER_T; //打印用户信息 三种写法 userArr[10] userArr[ ] userArr*void printUserInfo(USER_T userArr[10]); //用户添加 用户结构体添加到用户结构体数组void addUser(USER_T newuser , USER_T userArr[10]);//把新用户添加到userArr[10]数组当中 int userCheck(char name[],USER_T userArr[10]); #endif
七、user.c
#include"user.h"#include<stdio.h>#include<string.h>//memcpy extern count; //外部引用 引入main.c中的count(全局变量) //打印用户信息void printUserInfo(USER_T userArr[10]){ int i=0; printf("%d\n",count); for(i=0;i<count;i++) { printf("%d\t%s\t%s\t",userArr[i].ID,userArr[i].name,userArr[i].pwd); switch(userArr[i].role) { case ADMIN: printf("管理员\n"); break; case MANAGER: printf("经理\n"); break; case WAITER: printf("服务员\n"); break; default : break; } } } //用户添加 用户结构体添加到用户结构体数组void addUser(USER_T newuser , USER_T userArr[10]){ //userArr[count++]=newuser; memcpy(&userArr[count++],&newuser,sizeof(USER_T));//地址内存拷贝赋值 取地址 数组 变量名 长度} int userCheck(char name[],USER_T userArr[10]){ int i=0; for(i=0;i<count;i++) { if(strcmp(userArr[i].name,name)==0) { return i; } } return -1;}
八、loginWin.h
#ifndef LOGINWIN_H#define LOGINWIN_H#include"user.h" //登录的初始化--登录窗口的展示int loginInit(); int doLogin(char name[],char pwd[]);//登录输入用户名密码 函数返回:角色role是int int Jude(char *name,char *pwd,USER_T userArr[]); #endif
九、loginWin.c
#include"loginWin.h"#include"Cwindow.h"#include "Ctool.h"#include"user.h"//userArr[10] 1是admin 2是 manager 3 是waiter#include<stdio.h>//printf#include<string.h>//strcmp#include<windows.h> #include<stdlib.h> extern USER_T userArr[10];//引入外部变量 结构体数组定义时做全局变量extern count;//count在main.c中是全局变量 int loginInit(){ char name[9]={0};//定义用户名 char pwd[7]={0};//定义密码 int role= -2;//初始化登录返回的结果 不能0 1 2 -1(有含义) WIN_T loginWin={5,5,24,16};//有两个没填 部分初始化 控件结构体数组{0} ctrlCount=0 //标签文本控件 CONTROL_T title={19,7,10,2,0,0,0,LABEL,"点菜系统"}; CONTROL_T labName={10,9,10,3,0,0,0,LABEL,"请输入账号:"}; CONTROL_T labPwd={10,12,10,3,0,0,0,LABEL,"请输入密码:"}; //编辑器控件 CONTROL_T editName={25,9,10,3,10,2,1,EDIT,""}; CONTROL_T editPwd={25,12,10,3,8,0,0,EDIT,""}; //按钮控件 CONTROL_T btnok={10,15,8,3,0,0,0,BUTTON,"登录"}; CONTROL_T btncancle={26,15,8,3,0,0,0,BUTTON,"返回"}; //添加控件 void addControl(参数1:控件结构体(控件) 参数2:控件数组 参数3:控件个数); //通过下标将控件ctrl放到控件数组ctrlArr[20]当中 在登录窗口界面中添加控件 //数组作为实参时直接写数组名ctrlArr即可,数组名(起始地址) addControl(title,loginWin.ctrlArr,&loginWin.ctrlCount); addControl(labName,loginWin.ctrlArr,&loginWin.ctrlCount); addControl(labPwd,loginWin.ctrlArr,&loginWin.ctrlCount); addControl(editName,loginWin.ctrlArr,&loginWin.ctrlCount); addControl(editPwd,loginWin.ctrlArr,&loginWin.ctrlCount); addControl(btnok,loginWin.ctrlArr,&loginWin.ctrlCount); addControl(btncancle,loginWin.ctrlArr,&loginWin.ctrlCount); printf("控件个数,%d\n",loginWin.ctrlCount);//ctrlCount控件个数 //展示窗口和每一个控件 showWindow(loginWin); //窗口执行函数 告知当前回车的按钮的下标是多少 winRun(&loginWin); switch(loginWin.foucsIndex){ case 5: role = Jude(loginWin.ctrlArr[3].content,loginWin.ctrlArr[4].content,userArr); gotoxy(27,17); if(role==-1)//失败 { printf("登录失败\n"); // return 0;//0 -- 登录界面 有bug登录失败第二次的才正常 Sleep(2000); system("cls"); loginInit(); } else{ printf("登录成功\n"); Sleep(1000); system("cls"); switch(role){ case ADMIN: adminInit(); return 1;//ADMIN case MANAGER: managerInit(); return 2;//MANAGER case WAITER: waiterInit(); return 3;//WAITER } } break; case 6: printf("返回\n"); return -1; default: break; }} int Jude(char *name,char *pwd,USER_T userArr[]){ int i=0; for(;i<count;i++) { //对比用户名和密码都要相等 if(strcmp(name,userArr[i].name)==0&&strcmp(pwd,userArr[i].pwd)==0) { // 用户名密码相等表示登录成功 登录成功返回角色 return userArr[i].role; } } //登录失败 return -1; }
十、Admin.h
#ifndef ADMIN_H#define ADMIN_H //管理员窗口的初始化int adminInit(); #endif
十一、Admin.c
#include"Admin.h"#include"Cwindow.h"#include "Ctool.h"#include<stdio.h>#include<stdlib.h> int adminInit(){ WIN_T Admin={3,3,25,23}; CONTROL_T titleguan={19,5,10,2,0,0,0,LABEL,"管理员界面"}; CONTROL_T btntaizhuo={19,9,8,3,0,0,0,BUTTON,"台桌管理"}; CONTROL_T btncaipu={19,12,8,3,0,0,0,BUTTON,"菜谱管理"}; CONTROL_T btnrenyuan={19,15,8,3,0,0,0,BUTTON,"人员管理"}; CONTROL_T btnzhuxiao={19,18,8,3,0,0,0,BUTTON,"注销"}; CONTROL_T btntuichu={19,21,8,3,0,0,0,BUTTON,"退出"}; //添加控件 void addControl(参数1:控件结构体(控件) 参数2:控件数组 参数3:控件个数); addControl(titleguan,Admin.ctrlArr,&Admin.ctrlCount); addControl(btntaizhuo,Admin.ctrlArr,&Admin.ctrlCount); addControl(btncaipu,Admin.ctrlArr,&Admin.ctrlCount); addControl(btnrenyuan,Admin.ctrlArr,&Admin.ctrlCount); addControl(btnzhuxiao,Admin.ctrlArr,&Admin.ctrlCount); addControl(btntuichu,Admin.ctrlArr,&Admin.ctrlCount); printf("控件个数,%d\n",Admin.ctrlCount); showWindow(Admin); winRun(&Admin); switch(Admin.foucsIndex){ case 3: system("cls"); guanrenInit(); //return 4; bug 刷新第二次才可以 break; case 5: system("cls"); loginInit(); break; default: break; } }
十二、Manager.h
#ifndef MANAGER_H#define MANAGER_H //经理窗口的初始化int managerInit(); #endif
十三、Manager.c
#include"Manager.h"#include"Cwindow.h"#include "Ctool.h"#include<stdio.h>#include<stdlib.h> int managerInit(){ WIN_T Manager={3,3,25,23};//部分初始化 控件结构体数组{0} ctrlCount=0 CONTROL_T titlejingli={19,5,10,2,0,0,0,LABEL,"经理功能界面"}; CONTROL_T btnyingshou={19,9,8,3,0,0,0,BUTTON,"营收汇总"}; CONTROL_T btnzhuxiao={19,12,8,3,0,0,0,BUTTON,"注销"}; CONTROL_T btntuichu={19,15,8,3,0,0,0,BUTTON,"退出"}; //添加控件 void addControl(参数1:控件结构体(控件) 参数2:控件数组 参数3:控件个数); addControl(titlejingli,Manager.ctrlArr,&Manager.ctrlCount); addControl(btnyingshou,Manager.ctrlArr,&Manager.ctrlCount); addControl(btnzhuxiao,Manager.ctrlArr,&Manager.ctrlCount); addControl(btntuichu,Manager.ctrlArr,&Manager.ctrlCount); printf("控件个数,%d\n",Manager.ctrlCount); showWindow(Manager); winRun(&Manager); switch(Manager.foucsIndex){ case 3: system("cls"); loginInit(); break; default: break; }}
十四、Waiter.h
#ifndef WAITER_H#define WAITER_H //服务员窗口的初始化int waiterInit(); #endif
十五、Waiter.c
#include"Waiter.h"#include"Cwindow.h"#include "Ctool.h"#include<stdio.h> int waiterInit(){ WIN_T Waiter={3,3,25,25};//部分初始化 控件结构体数组{0} ctrlCount=0 CONTROL_T titlefuwu={19,5,10,2,0,0,0,LABEL,"服务员功能界面"}; CONTROL_T btnkaizhuo={19,9,10,3,0,0,0,BUTTON,"开桌"}; CONTROL_T btndiancai={19,12,10,3,0,0,0,BUTTON,"点菜"}; CONTROL_T btnyingyee={19,15,10,3,0,0,0,BUTTON,"营业额查询"}; CONTROL_T btnyi={19,18,10,3,0,0,0,BUTTON,"已买/未买单查询"}; CONTROL_T btnzhuxiao={19,21,10,3,0,0,0,BUTTON,"注销"}; CONTROL_T btntuichu={19,24,10,3,0,0,0,BUTTON,"退出"}; //添加控件 void addControl(参数1:控件结构体(控件) 参数2:控件数组 参数3:控件个数); addControl(titlefuwu,Waiter.ctrlArr,&Waiter.ctrlCount); addControl(btnkaizhuo,Waiter.ctrlArr,&Waiter.ctrlCount); addControl(btndiancai,Waiter.ctrlArr,&Waiter.ctrlCount); addControl(btnyingyee,Waiter.ctrlArr,&Waiter.ctrlCount); addControl(btnyi,Waiter.ctrlArr,&Waiter.ctrlCount); addControl(btnzhuxiao,Waiter.ctrlArr,&Waiter.ctrlCount); addControl(btntuichu,Waiter.ctrlArr,&Waiter.ctrlCount); printf("控件个数,%d\n",Waiter.ctrlCount); showWindow(Waiter); winRun(&Waiter); switch(Waiter.foucsIndex){ case 6: system("cls"); loginInit(); break; default: break; }}
读到这里,这篇“C语言如何实现点菜系统”文章已经介绍完毕,想要掌握这篇文章的知识点还需要大家自己动手实践使用过才能领会,如果想了解更多相关内容的文章,欢迎关注编程网行业资讯频道。