[C语言] 实现简单的菜单式互动程序

2019-07-29  本文已影响0人  入梦瞌睡

1.程序编写目的

编写该程序主要是为了熟悉C语言中的一些常用函数与循环语句的用法,并锻炼自己对于程序设计的逻辑,这对于初学者来说是十分必要的。

2.实现该程序所需要的技术

2.1常用函数printf() scanf() getchar()等

具体语法:

int a = 3;

  • printf("%d",a);
    其中,
    %d用来输出整型变量(int 在64位中占4个字节)
    %f用来输出float变量(64位占4个字节)
    %f也用来输出double变量( 64位占8个字节)
    %ld用来输出long( 64位占4个字节)
    %c用来输出char类型变量( 64位占1个字节)
    %s用来输出char *类型变量(scanf中同理)
  • 另外,可以用%02d来控制整型输出方式(2表示一共占2位,0表示空闲部分用0补充),此时输出为03
  • %f也可以进行格式的控制,如%.1f则输出的float或double数只会留下小数点后1位
  • scanf("%d",&a);
    其中&a表示变量a的地址,即将输入的内容根据a的地址送到对应的存储空间中(ps:新版本VS一般要求使用scanf_s())
  • getchar()能直接读取缓冲区中的下一个字符,有些软件没法使用fflush()函数来清空缓冲区,则可以
char ch;
while ((ch = getchar() )!= '\n');

使用这两个语句来实现清空缓冲区,以避免下一个getchar()或scanf

2.2练习程序设计中常用的循环语句for()、while()、do{ }while()
  • for循环主要强调固定次数,它一般与数组相搭配
  • while循环与do while循环主要用于条件判断类型的,二者的区别主要在于,后者必定会执行一次,前者不一定

2.程序需要实现的功能:

2.1程序开始时,需要输入密码(默认为123),最多有4次机会,如果连续输入错误4次,则程序停止

如图:


密码检查.png
2.2输入正确的密码后(默认密码为123),显示互动菜单,如图所示:
菜单显示.png
2.3当输入3时,会显示余额(余额为一个全局变量),如图所示:
3.显示余额.JPG
2.4当输入2时,会询问需要存款的金额,并且该金额会使余额发生改变,如图所示:
2.存款.JPG
2.5当输入1时,会询问需要取出款的金额,如果欲取出的金额大于余额,会提示错误,如果小于余额,则余额会发生变化,如图所示:
1.取款.png

3.具体实现步骤

3.1密码检查

代码编写思路:

(1)由于有4次输入机会,即设计到反复输入,因此最外层必然会套一层while循环,并且要设计一个Int变量(input_num)用于记录错误次数
(2)密码是否正确需要使用if语句进行判断,如果正确,则使用break;结束循环,如果错误,则input_num++并要求重新输入
(3)当密码输入错误4次,则直接在主函数中使用return;结束整个程序(主函数类型是void,因此直接使用return;就可以结束程序)

具体代码如下:

printf("请输入密码:");
scanf_s("%d", &password_s);
while (1) {
    if (input_num == 3) {
        printf("机会已经用光,此卡已经冻结\n");
        return;
    }
    if (password_s != password) {
        input_num++;
        printf("密码错误!还有%d次机会,请重新输入:", (3-input_num));
        scanf_s("%d", &password_s);
    }
    else {
        printf("密码正确,欢迎!\n");
        break;
    }
        
}
while ((ch = getchar()) != '\n');//清空缓冲区
3.2菜单界面输出

直接使用printf()即可

printf("***********************************\n");
printf("****  1.取款         2.存款  ******\n");//开始存款 
printf("****  3.显示余额             ******\n");
printf("****  4.设置密码     5.退出  ******\n");//请输入原始、新密码
printf("***********************************\n");
printf("请选择操作:");
scanf_s("%d", &choice);//用来输入操作数
3.3判断是否输入的数字是否错误(是否在1至5之间)
if (choice < 1 || choice > 5) {
    printf("输入有误,请重新输入!\n");
    while ((ch = getchar() )!= '\n');
    scanf_s("%d", &choice);
}
else{
  //输入无误,判断是1,2, 3, 4, 5中的哪个
}

当 1<choice<5 时
else中需要用语句来判断到底是1,2, 3, 4, 5中的哪个,这个语句可以使用多个if else语句,也可以直接使用switch语句,这里采用后者:

switch (choice){
case 1:
    while (flag == 'Y') {
        printf("请输入取款金额!\n");//取款成功,当前余额为
        scanf_s("%d", &money);
        if (money > remains) {
            printf("余额不足,是否重新输入?(Y/N)\n");
            while ((ch = getchar()) != '\n');//清空缓存区
            scanf_s("%c", &flag);
        }
        else {
            remains = remains - money;
            printf("取款成功!\n");
            flag = 'N';
            }
        }
    break;
case 2:
    printf("请输入存款金额!\n");
    scanf_s("%d", &money);
    remains = remains + money;
    printf("存款成功!\n");
    break;
case 3:
    printf("您的余额为:%d\n", remains);
    break;
case 4:
    printf("请输入新密码\n");
    scanf_s("%d",&password);
    printf("设置成功!\n");
    break;
case 5:
    break;
default:
    break;
            }
}

全部一起看比较长,看起来很复杂,我们逐条分析
先挑比较简单的来看:

case 3:
    printf("您的余额为:%d\n", remains);
    break;
case 4:
    printf("请输入新密码\n");
    scanf_s("%d",&password);
    printf("设置成功!\n");
    break;

case 3与case4就是单纯的printf()输出与scanf_s输入

case 2:
    printf("请输入存款金额!\n");
    scanf_s("%d", &money);
    remains = remains + money;
    printf("存款成功!\n");
    break;

case 2为存款则需要通过scanf_s来获取存款金额,并通过计算改变remains的值,这里的remains是一个全局变量

case 1:
    while (flag == 'Y') {
        printf("请输入取款金额!\n");//取款成功,当前余额为
        scanf_s("%d", &money);
        if (money > remains) {
            printf("余额不足,是否重新输入?(Y/N)\n");
        while ((ch = getchar()) != '\n');//清空缓存区
            scanf_s("%c", &flag);
        }
        else {
            remains = remains - money;
            printf("取款成功!\n");
            flag = 'N';
            }
        }
    break;

case 1 比较复杂,首先先讲一下编写思路:

(1)首先,由于涉及到余额不足的情况,因此这是一个有可能多次重复运行的代码,所以说最外层套一个while循环
(2)由于要判断余额与取款的多少,因此要使用if else语句
①如果余额更大,则说明取款成功,则运行 remains = remains - money;
②如果判断结果是余额更小,说明取款失败,则输出“余额不足”,并询问是否重新输入
ps:要注意的是由于询问是否重新输入使用的是%c,即使以字符的形式进行输入的,因此需要用 while ((ch = getchar()) != '\n'); 来清空缓存区,避免换行符\n被下一次循环中的scanf_s读取
(3)由于需要一个条件来判断是否重新输入(Y/N),且即使是需要重新输入,也需要进入下一次循环,因此要定义一个char类型变量flag,初始化时赋值为'Y',这个flag也会作为while的判断条件,来保证需要重新输入的时候能够进入下一次循环,不需要时,则不再循环

3.4switch语句后再次提醒继续输入

在switch语句中的最后(switch的大括号外面的后面)加上,以提醒继续输入

printf("操作完成,请继续输入:\n");
while ((ch = getchar()) != '\n');//清空缓存区
scanf_s("%d", &choice);

4.总结

4.1完整代码:
#include<stdio.h>
void main() {
    
    int choice;
    char ch;
    int password = 123;
    int password_s;
    int input_num = 0;//用来判断输错密码的次数
    int money;//money为取出来的钱
    char flag = 'Y';//在余额不足的时候用来判断是否取钱
    int remains = 200;//而余额为200
    printf("***********************************\n");
    printf("**********   欢迎光临   ***********\n");
    printf("***********************************\n");
    printf("请输入密码:");
    scanf_s("%d", &password_s);
    while (1) {
        if (input_num == 3) {
            printf("机会已经用光,此卡已经冻结\n");
            return;
        }
        if (password_s != password) {
            input_num++;
            printf("密码错误!还有%d次机会,请重新输入:", (3-input_num));
            scanf_s("%d", &password_s);
        }
        else {
            printf("密码正确,欢迎!\n");
            break;
        }
        
    }
    while ((ch = getchar()) != '\n');//清空缓存区
    /*********************上面的为密码判断*************************/
    printf("***********************************\n");
    printf("****  1.取款         2.存款  ******\n");//开始存款 
    printf("****  3.显示余额             ******\n");
    printf("****  4.设置密码     5.退出  ******\n");//请输入原始、新密码
    printf("***********************************\n");
    printf("请选择操作:");
    scanf_s("%d", &choice);
    while (choice!=5){
        if (choice < 1 || choice > 5) {
            printf("输入有误,请重新输入!\n");
            
            while ((ch = getchar() )!= '\n');
            scanf_s("%d", &choice);
        }
        else {
            flag = 'Y';//每次都重新赋予取钱的权限
            switch (choice)
            {
            case 1:
                while (flag == 'Y') {
                    printf("请输入取款金额!\n");//取款成功,当前余额为
                    scanf_s("%d", &money);
                    if (money > remains) {
                        printf("余额不足,是否重新输入?(Y/N)\n");
                        while ((ch = getchar()) != '\n');//清空缓存区
                        scanf_s("%c", &flag);
                    }
                    else {
                        remains = remains - money;
                        printf("取款成功!\n");
                        flag = 'N';
                        //while ((ch = getchar()) != '\n');//清空缓存区
                    }
                }
                //存款成功,当前余额为20->余额不足,是否继续Y/N
                break;
            case 2:
                printf("请输入存款金额!\n");
                scanf_s("%d", &money);
                remains = remains + money;
                //while ((ch = getchar()) != '\n');//清空缓存区
                printf("存款成功!\n");
                break;
            case 3:
                printf("您的余额为:%d\n", remains);
                break;
            case 4:
                printf("请输入新密码\n");
                scanf_s("%d",&password);
                printf("设置成功!\n");
                break;
            case 5:
                break;
            default:
                break;
            }
            printf("操作完成,请继续输入:\n");
            while ((ch = getchar()) != '\n');//清空缓存区
            scanf_s("%d", &choice);
        }
    }
}

4.2总结:

(1)这里的代码全部写在了主函数中,使主函数显得比较臃肿,可以将密码检测的那一部分语句,以及菜单显示那部分的语句,分别放到一个对应的函数中,这样就能缩短主函数的篇幅
(2)代码还有许多漏洞,比如当输入字母或是特殊符号的时候,会有比较严重的错误,本人的一个解决思路是将choice变量改为字符串类型,用ASCII码来实现上述内容(即将1,2,3,4,5换为对应的ASCII码等)
上一篇下一篇

猜你喜欢

热点阅读