当前位置:嗨网首页>书籍在线阅读

18-混合字符和数值输入

  
选择背景色: 黄橙 洋红 淡粉 水蓝 草绿 白色 选择字体: 宋体 黑体 微软雅黑 楷体 选择字体大小: 恢复默认

8.7.3 混合字符和数值输入

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

void count(void)
{
     int n, i;
     printf("Count how far? Enter an integer:\n");
     scanf("%d", &n);
     for (i = 1; i <= n; i++)
          printf("%d\n", i);
}

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

重写 get_first() ,使其返回下一个非空白字符而不仅仅是下一个字符,即可修复这个问题。我们把这个任务留给读者作为练习。另一种方法是,在 count() 函数中清理换行符,如下所示:

void count(void)
{
     int n, i;
     printf("Count how far? Enter an integer:\n");
     n = get_int();
     for (i = 1; i <= n; i++)
          printf("%d\n", i);
     while (getchar() != '\n')
          continue;
}

该函数借鉴了程序清单8.7中的 get_long() 函数,将其改为 get_int() 获取 int 类型的数据而不是 long 类型的数据。回忆一下,原来的 get_long() 函数如何检查有效输入和让用户重新输入。程序清单8.8演示了菜单程序的最终版本。

程序清单8.8  menuette.c 程序

/* menuette.c -- 菜单程序 */
#include <stdio.h>
char get_choice(void);
char get_first(void);
int get_int(void);
void count(void);
int main(void)
{
     int choice;
     while ((choice = get_choice()) != 'q')
     {
          switch (choice)
          {
               case 'a':  printf("Buy low, sell high.\n");
                          break;
               case 'b':  putchar('\a');    /* ANSI */
                          break;
               case 'c':  count();
                          break;
               default:   printf("Program error!\n");
                          break;
          }
     }
     printf("Bye.\n");
     return 0;
}
void count(void)
{
     int n, i;
     printf("Count how far? Enter an integer:\n");
     n = get_int();
     for (i = 1; i <= n; i++)
          printf("%d\n", i);
     while (getchar() != '\n')
          continue;
}
char get_choice(void)
{
     int ch;
     printf("Enter the letter of your choice:\n");
     printf("a. advice           b. bell\n");
     printf("c. count            q. quit\n");
     ch = get_first();
     while ((ch < 'a' || ch > 'c') && ch != 'q')
     {
          printf("Please respond with a, b, c, or q.\n");
          ch = get_first();
     }
     return ch;
}
char get_first(void)
{
     int ch;
     ch = getchar();
     while (getchar() != '\n')
          continue;
     return ch;
}
int get_int(void)
{
     int input;
     char ch;
     while (scanf("%d", &input) != 1)
     {
          while ((ch = getchar()) != '\n')
               putchar(ch);  // 处理错误输出
          printf(" is not an integer.\nPlease enter an ");
          printf("integer value, such as 25, -178, or 3: ");
     }
     return input;
}

下面是该程序的一个运行示例:

Enter the letter of your choice:
a. advice           b. bell
c. count            q. quit
a
Buy low, sell high.
Enter the letter of your choice:
a. advice           b. bell
c. count            q. quit
count
Count how far? Enter an integer:
two
two is not an integer.
Please enter an integer value, such as 25, -178, or 3: 5
1
2
3
4
5
Enter the letter of your choice:
a. advice           b. bell
c. count            q. quit
d
Please respond with a, b, c, or q.
q

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

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