系统菜单的设计
界面要求:
1、 要求每次进入各级菜单时清屏
2、 “主菜单”标题:学生信息管理系统
3、 以“主菜单”形式显示内容
a) “1.学生信息增加”
b) “2.学生信息显示”
c) “3.学生信息查找”
d) “4.学生信息修改”
e) “5.学生信息删除”
f) “0.退出”
4、 选择操作上述菜单项时进入相应“二级菜单”功能界面,界面要求
a) 清屏
b) 标题:“学生信息XX”
c) 显示“该功能未实现,按任意键返回上一级。”
d) 按任意键返回到主菜单,主菜单显示要求按3要求。
5、 在“主菜单”界面时,按0键结束程序。
对于该菜单的实现比较简单,这里小编只提供一些思路。首先我们要将基本的菜单内容输出出来:
只需要代码:
printf("1.学生信息增加\n\n2.学生信息显示\n\n3.学生信息查找\n\n4.学生信息修改\n\n5.学生信息删除\n\n0.退出\n");
即可。
接下来是进行菜单选项,这一功能的实现需要我们用条件判断语句实现。但如果使用if语句会使代码量增加并且变得繁琐。所以我们可以改用switch语句进行操作。如这样:
int a;
cin>>a;
switch(a)
{
case 1:
printf("学生信息增加\n该功能未实现,按任意键返回上一级。\n");
break;
case 2:
printf("学生信息显示\n该功能未实现,按任意键返回上一级。\n");
break;
case 3:
printf("学生信息查找\n该功能未实现,按任意键返回上一级。\n");
break;
case 4:
printf("学生信息修改\n该功能未实现,按任意键返回上一级。\n");
break;
case 5:
printf("学生信息删除\n该功能未实现,按任意键返回上一级。\n");
break;
case 0:
printf("退出");
}
这里要注意,如果在每个判断语句结尾处不加break的话会使程序继续向下读取,如在case 1:语句结尾不加break的话,那么在输出完“学生信息增加\n该功能未实现,按任意键返回上一级。\n”内容后还会继续输出“学生信息显示\n该功能未实现,按任意键返回上一级。”直到遇到break或末尾处才会结束。switch语句的功能其实类似于goto,只是将程序立刻带到标记处,而这里我们采用case的形式来标记。
为了让程序不断的运行,直到我们选择的退出选项才终止,我们可以将程序放入循环中如:
#include
#include
#include
#include
using namespace std;
int main()
{
int a;
while(a!=0)
{
printf("1.学生信息增加\n\n2.学生信息显示\n\n3.学生信息查找\n\n4.学生信息修改\n\n5.学生信息删除\n\n0.退出\n");
cin>>a;
switch(a)
{
case 1:
printf("学生信息增加\n该功能未实现,按任意键返回上一级。\n");
break;
case 2:
printf("学生信息显示\n该功能未实现,按任意键返回上一级。\n");
break;
case 3:
printf("学生信息查找\n该功能未实现,按任意键返回上一级。\n");
break;
case 4:
printf("学生信息修改\n该功能未实现,按任意键返回上一级。\n");
break;
case 5:
printf("学生信息删除\n该功能未实现,按任意键返回上一级。\n");
break;
case 0:
printf("退出");
}
}
return 0;
}
但这样的循环会出现问题:
变量a我们是在循环外面定义的,而输入却是在循环中,也就是说初始化的变量a是随机值,这就有种可能,即我们还没输入循环就结束了。这样的菜单显然是失败的。那么为了解决这个问题我们需要使用do-while循环:
#include
#include
#include
#include
using namespace std;
int main()
{
int a;
do
{
printf("1.学生信息增加\n\n2.学生信息显示\n\n3.学生信息查找\n\n4.学生信息修改\n\n5.学生信息删除\n\n0.退出\n");
cin>>a;
switch(a)
{
case 1:
printf("学生信息增加\n该功能未实现,按任意键返回上一级。\n");
break;
case 2:
printf("学生信息显示\n该功能未实现,按任意键返回上一级。\n");
break;
case 3:
printf("学生信息查找\n该功能未实现,按任意键返回上一级。\n");
break;
case 4:
printf("学生信息修改\n该功能未实现,按任意键返回上一级。\n");
break;
case 5:
printf("学生信息删除\n该功能未实现,按任意键返回上一级。\n");
break;
case 0:
printf("退出");
}
}while(a!=0);
return 0;
}
这样无论如何程序都会将循环中的内容执行一次,就解决了上述问题。
但是现在这个菜单还有很多缺点,如:在输入菜单选项后选项中内容会在菜单下面显示,而不是出现一个新画面
这样会使画面很杂乱,所以还需要加上我们之前说过的清屏程序:
#include
#include
#include
#include
using namespace std;
int main()
{
int a;
do
{
system("cls");
printf("1.学生信息增加\n\n2.学生信息显示\n\n3.学生信息查找\n\n4.学生信息修改\n\n5.学生信息删除\n\n0.退出\n");
cin>>a;
switch(a)
{
case 1:
system("cls");
printf("学生信息增加\n该功能未实现,按任意键返回上一级。\n");
break;
case 2:
system("cls");
printf("学生信息显示\n该功能未实现,按任意键返回上一级。\n");
break;
case 3:
system("cls");
printf("学生信息查找\n该功能未实现,按任意键返回上一级。\n");
break;
case 4:
system("cls");
printf("学生信息修改\n该功能未实现,按任意键返回上一级。\n");
break;
case 5:
system("cls");
printf("学生信息删除\n该功能未实现,按任意键返回上一级。\n");
break;
case 0:
system("cls");
}
}while(a!=0);
return 0;
}
好了,加上了system(“cls”);程序后又出现了新问题:在我们选择了菜单选项后会发现屏闪了一下又恢复了原来界面。这正是清屏程序造成的。我们现在需要让画面在菜单选项后的界面停滞,当我们输入任意键后再返回。只需要加上getch()即可,该程序即解决了需要停滞的问题,又解决了输入任意键返回上一级的问题。最终完整代码如下:
#include
#include
#include
#include
using namespace std;
int main()
{
int a;
char t;
do
{
system("cls");
printf("1.学生信息增加\n\n2.学生信息显示\n\n3.学生信息查找\n\n4.学生信息修改\n\n5.学生信息删除\n\n0.退出\n");
scanf("%d",&a);
switch(a)
{
case 1:
system("cls");
printf("学生信息增加\n该功能未实现,按任意键返回上一级。\n");
t=getch();
break;
case 2:
system("cls");
printf("学生信息显示\n该功能未实现,按任意键返回上一级。\n");
t=getch();
break;
case 3:
system("cls");
printf("学生信息查找\n该功能未实现,按任意键返回上一级。\n");
t=getch();
break;
case 4:
system("cls");
printf("学生信息修改\n该功能未实现,按任意键返回上一级。\n");
t=getch();
break;
case 5:
system("cls");
printf("学生信息删除\n该功能未实现,按任意键返回上一级。\n");
t=getch();
break;
case 0:
system("cls");
}
}
while(a!=0);
return 0;
}
这只是小编做的一个简洁版的思路,当然完成一个菜单的方法还有很多,欢迎大家来一起讨论。至于让你的菜单更精致一些,只需要改改细节就好了。
根据“实践项目1、2“Q题的内容进入实质性设计内容如下:
1、现有学生信息包含三部分:学号(10位数字组成的字符串)、姓名(10位英文字母组成的字符串)、成绩(0~100整数)。
2、按照功能菜单对应的功能完成一个班的数据信息的输入Add、显示Display、查找Locate、修改Modify、删除Delete。其中学号是每名学生的关键字。
3、输入信息时按照关键字先查找是否存在,如不存在,提示输入信息
4、显示信息时按照两种显示方式(两种方式可以设计子菜单):一种是输入学生的关键字,显示特定学生,找到显示,找不到提示“未曾找到,无法操作!”;另一种是把当前所有学生的信息显示出来,要注意数据最好是按照每屏显示若干条信息。
5、查找信息时按照4的第一种方式进行
6、修改信息时先输入要修改学生的关键字,如找到,显示信息,然后提示是否修改,确认修改后进行修改,取消修改后退出;如没有找到要修改的学生,提示“未曾找到,无法操作!”
7、删除信息是先输入要删除学生的关键字,如找到,显示信息,然后提示是否删除,确认删除后进行删除,取消删除后退出;如没有找到要删除的学生,提示“未曾找到,无法操作!”
8、所实现的各个功能可参考由实践2最后一道题设计的函数中实现。注意各个函数时候需要传递参数,传递参数的类型与个数要确定。
ExitSystem();
AddInfo();
DisplayInfo();
LocateInfo();
ModifyInfo();
DeleteInfo();
这个菜单的难度较上一个菜单的难度有了很大的提升。我们需要运用函数、结构体等功能来完成。首先我们明确各个函数的功能然后逐渐完善各个函数最后再用主函数来连接。
由于我们需要储存学生的名字,学号,成绩。所以干脆建立一个结构体:
const int N = 1e5+7;
struct book
{
string name,num;//名字、学号
int grade;//成绩
} s[N];//结构体数组
这里注意,结构体由于在各个函数中都需要使用,所以需要定义为全局变量。
该函数意为储存系统,但是我不太明白它具体存些啥,所以我就用它来存了一些初始的学生信息:
void ExitSystem()
{
s[1].name="Jake";
s[1].num="2004020201";
s[1].grade=59;
s[2].name="Tom";
s[2].num="2004020202";
s[2].grade=62;
s[3].name="Make";
s[3].num="2004020203";
s[3].grade=73;
}
先存三个学生信息,”杰克“、“汤姆”、“梅克”。
该函数为输入系统,根据题目要求“输入信息时按照关键字先查找是否存在,如不存在,提示输入信息”。所以先根据”关键字“进行一次查找,信息存在时将信息输出,不存在时进行输入:
void AddInfo()
{
cout<<"请输入关键字:";
string t;
cin>>t;
int x=0,j;
for(j=1; j<=i; j++)
{
if(s[j].num==t)
{
x++;
break;
}
}
if(x==0)
{
i++;
cout<<"信息不存在,请输入:"<>s[i].name;
cout<<"\n学号:";
cin>>s[i].num;
cout<<"\n成绩:";
cin>>s[i].grade;
}
else
{
cout<
这里为了简单,直接采取了循环的方法来进行查找信息,所以在最前面我们还要定义一个全局变量i,并且初始化值为3(因为我们事先储存了三名同学的信息,如果你事先储存了n名同学的信息,那么这里i的值就要初始化为n)
该函数功能为显示,根据要求“显示信息时按照两种显示方式(两种方式可以设计子菜单):一种是输入学生的关键字,显示特定学生,找到显示,找不到提示“未曾找到,无法操作!”;另一种是把当前所有学生的信息显示出来,要注意数据最好是按照每屏显示若干条信息。”
做出:
void DisplayInfo()
{
int a,j;
cout<<"1.显示全部信息"<>a;
system("cls");
if(a==1)
{
for(int j=1; j<=i; j++)
{
cout<<"Name:"<>t;
int x=0;
for(j=1; j<=i; j++)
{
if(s[j].num==t)
{
x++;
break;
}
}
if(x==0)
{
cout<<"未曾找到,无法操作!"<
这里比较好理解,显示全部依然是用循环所有进行的。
该功能为查找,与显示的功能一样
void LocateInfo()
{
cout<<"请输入关键字:";
string t;
cin>>t;
int x=0,j;
for(j=1; j<=i; j++)
{
if(s[j].num==t)
{
x++;
break;
}
}
if(x==0)
{
cout<<"未曾找到,无法操作!"<
下面是最难的两个功能了
首先来说修改功能,这比删除信息要容易点,我们要通过遍历的方法来找到你想修改的信息的关键字,然后将该关键字的信息全部展示出来,再询问使用者是否修改。这里需要一个间接的变量来标记找到的信息所在的结构体数组的位置,然后将其信息进行修改:
void ModifyInfo()
{
cout<<"请输入关键字:";
string t,b;
cin>>t;
int x=0,j;
for(j=1; j<=i; j++)//j即是用来标记的间接变量
{
if(s[j].num==t)
{
x++;
break;
}
}
if(x==0)
{
cout<<"未曾找到,无法操作!"<>b;
if(b=="Y"||b=="y"||b=="yes"||b=="Yes"||b=="YES")
{
cout<<"请输入:"<>s[j].name;
cout<<"\n学号:";
cin>>s[j].num;
cout<<"\n成绩:";
cin>>s[j].grade;
}
}
}
删除信息也要通过遍历的方法来找到你想删除的信息的关键字,然后将该关键字的信息全部展示出来,再询问使用者是否删除。这里需要一个间接的变量来标记找到的信息所在的结构体数组的位置,然后将其信息进行删除。这里的难点是删除之后结构体数组中被删除的位置会变成空的,这样就会影响整个结构体数组的顺序,从而使我们前面查找显示输入等功能混乱。所以要将删除后的空位置用后面的未删除部分补上:
void DeleteInfo()
{
cout<<"请输入要删除的学生的关键字:";
string t,b;
cin>>t;
int x=0,j;
for(j=1; j<=i; j++)
{
if(s[j].num==t)
{
x++;
break;
}
}
if(x==0)
{
cout<<"未曾找到,无法操作!"<>b;
if(b=="Y"||b=="y"||b=="yes"||b=="Yes"||b=="YES")
{
for(int a=j;a<=i-1;a++)//从被删除位置开始,后面依次向前覆盖
{
s[a].name=s[a+1].name;
s[a].num=s[a+1].num;
s[a].grade=s[a+1].grade;
}
i--;
cout<<"删除成功!"<
这样我们就实现了所有功能,最后的代码如下:
#include
#include
#include
using namespace std;
const int N = 1e5+7;
int i=3;
struct book
{
string name,num;
int grade;
} s[N];
void ExitSystem()
{
s[1].name="Jake";
s[1].num="2004020201";
s[1].grade=59;
s[2].name="Tom";
s[2].num="2004020202";
s[2].grade=62;
s[3].name="Make";
s[3].num="2004020203";
s[3].grade=73;
}
void AddInfo()
{
cout<<"请输入关键字:";
string t;
cin>>t;
int x=0,j;
for(j=1; j<=i; j++)
{
if(s[j].num==t)
{
x++;
break;
}
}
if(x==0)
{
i++;
cout<<"信息不存在,请输入:"<>s[i].name;
cout<<"\n学号:";
cin>>s[i].num;
cout<<"\n成绩:";
cin>>s[i].grade;
}
else
{
cout<>a;
system("cls");
if(a==1)
{
for(int j=1; j<=i; j++)
{
cout<<"Name:"<>t;
int x=0;
for(j=1; j<=i; j++)
{
if(s[j].num==t)
{
x++;
break;
}
}
if(x==0)
{
cout<<"未曾找到,无法操作!"<>t;
int x=0,j;
for(j=1; j<=i; j++)
{
if(s[j].num==t)
{
x++;
break;
}
}
if(x==0)
{
cout<<"未曾找到,无法操作!"<>t;
int x=0,j;
for(j=1; j<=i; j++)
{
if(s[j].num==t)
{
x++;
break;
}
}
if(x==0)
{
cout<<"未曾找到,无法操作!"<>b;
if(b=="Y"||b=="y"||b=="yes"||b=="Yes"||b=="YES")
{
cout<<"请输入:"<>s[j].name;
cout<<"\n学号:";
cin>>s[j].num;
cout<<"\n成绩:";
cin>>s[j].grade;
}
}
}
void DeleteInfo()
{
cout<<"请输入要删除的学生的关键字:";
string t,b;
cin>>t;
int x=0,j;
for(j=1; j<=i; j++)
{
if(s[j].num==t)
{
x++;
break;
}
}
if(x==0)
{
cout<<"未曾找到,无法操作!"<>b;
if(b=="Y"||b=="y"||b=="yes"||b=="Yes"||b=="YES")
{
for(int a=j;a<=i-1;a++)
{
s[a].name=s[a+1].name;
s[a].num=s[a+1].num;
s[a].grade=s[a+1].grade;
}
i--;
cout<<"删除成功!"<>a;
switch(a)
{
case 1:
system("cls");
AddInfo();
printf("按任意键返回上一级。\n");
t=getch();
break;
case 2:
system("cls");
DisplayInfo();
printf("按任意键返回上一级。\n");
t=getch();
break;
case 3:
system("cls");
LocateInfo();
printf("按任意键返回上一级。\n");
t=getch();
break;
case 4:
system("cls");
ModifyInfo();
printf("按任意键返回上一级。\n");
t=getch();
break;
case 5:
system("cls");
DeleteInfo();
printf("按任意键返回上一级。\n");
t=getch();
break;
case 0:
system("cls");
}
}
while(a!=0);
}
运行一下试试看:
运行后会先显示初始菜单
输入2:
显示一下全部信息
我们事先储存的信息就会显示出来
现在让我们输入一个同学的信息
名字和学号成绩如下:
再次查看全部信息,发现我们输入进去的新信息已经被录入
将杰克的信息删除试试
再次查找时杰克已经不见了(可怜的杰克)
好啦,今天的内容就这么多,总之做这种实践类的代码方法有很多,这里只是提供一种小编的思路,大家可以一起讨论,尝试。