20. C Primer Plus 8.7菜单浏览

8.7菜单浏览

许多计算机程序都把菜单作为用户界面的一部分。菜单给用户提供方便的同时,却给程序员带来了一些麻烦。

菜单给用户提供了一份响应程序的选项。例如:

理想状态是,用户输入程序所列选项之一,然后程序根据用户所选项完 成任务。作为一名程序员,自然希望这一过程能顺利进行。因此,第1个目标是:当用户遵循指令时程序顺利运行;第2个目标是:当用户没有遵循指 令时,程序也能顺利运行。由于难以预见用户在使用程序时的所有错误情况,因此第二个目标难以完成。

现在的应用程序通常使用图形界面,可以点击按钮、查看对话框、触摸 图标,而不是我们示例中的命令行模式。

但是,两者的处理过程大致相同给用户提供选项、检查并执行用户的响应、保护程序不受误操作的影响。

除 了界面不同,它们底层的程序结构也几乎相同。但是,使用图形界面更容易通过限制选项控制输入

8.7.1任务

菜单程序需要执行的任务:1.它要获取用户的响应,根据响应选择要执行的动作。

2.程序应该提供返回菜单的选项

C语言中的switch语句是根据选项决定行为的好工具,用户的每一个选择都可以对应一个特定的case标签。使用while循环语句可以实现重复访问菜单的功能。

因此,菜单程序的结果写成伪代码如下:

获取选项

当选项不是’q‘时

转至相应的选项并执行

获取下一个选项

8.7.2使执行更顺利

当我们决定实现这个程序时,就要开始考虑如何让程序顺利运行(顺利运行指的是,处理正确输入和错误输入时都能顺利运行)。例如,我们能做的是让“获取选项”部分的代码筛选掉不合适的响应,只把正确的响应传入switch,这表明需要为输入过程提供一个只返回正确响应的函数。结合while循环语句和switch语句,程序结构如下:

定义get_choice()函数只能返回’a'、‘b’、‘c’、‘q’。get_choice()用法和getchar()相同,两个函数都是获取一个值,并与终止值(如该例中的‘q’)做比较。default 语句可以方便调试。如果get_choice()函数没 能把返回值限制为菜单指定的几个选项值,default语句有助于发现问题所在。

get_choice()函数

下面伪代码是设计这个函数的一种方案:

显示选项

获取用户响应

当响应不合适时

提示用户再次输入

获取用户的响应

下面是一种简单而笨拙的实现:

缓冲输入依旧带来些麻烦,程序把用户每次按下 Return 键产生的换行符视为错误响应。为了让程序的界面更流畅,该函数应该跳过这些换行符。

这种问题有多种解决方案,(1).用名为get—first()的新函数替换getchar()函数,读取一行的第一个字符并丢弃剩余字符,优点:把类似于act这样的输入视为简单的a,而不是继续把act中的c作为选项c的一个有效响应,我们重写输入函数如下:

8.7.3混合字符和数值输入

我们知道输入混合字符和数值输入会产生一些问题,创建菜单也有这样的问题,例如,假设count()函数(选择c)的代码如下:

如果输入3作为响应,scanf()会读取3并把换行符留在输入队列中。下次调用get_choice()将导致get_first()返回这个换行符,从而导致我们不希望出现的行为。

重写get_first(),使其返回下一个非空白字符而不仅仅是下一个字符,即可修复这个问题。另一种方法是,在count()函数中清理换行符,如下所示:

该函数借鉴了程序清单8.7中的get—long()函数,将其改为get—int()获取int类型的数据而不是long类型的数据。

下列示例程序演示了菜单程序的最终版本:

输出结果如下:

要写出一个自己十分满意的菜单界面并不容易。但是,在开发了一种可 行的方案后,可以在其他情况下复用这个菜单界面。

了解上述程序示例后,我们要注意在处理较复杂的任务时,如何让函数把任务委派给另一个函数,这样可以让程序更模块化。

posted @ 2022-02-07 01:25  喻雅芬  阅读(71)  评论(0)    收藏  举报