一、使用缓冲输入存在的问题和解决办法
1.使用缓冲输入存在的问题
我们可以看到,当输入n的时候,程序会运行两次,这是因为行缓冲的存在,在输入n之后,我们还输入了换行符,换行符也会被getchar()捕捉到进行一次运行。
2.解决办法
我们可以使用while循环丢弃输入行最后的剩余内容,包括换行符。
二、混合数值和字符输入
1.存在的问题
假设程序要求用getchar()处理字符,用scanf()处理数字,getchar()不会跳过空格、换行符和制表符;但scanf()在处理数字时会跳过空格、换行符和制表符,这是同样会有换行符存在的干扰
由于换行符的出现,程序直接退出。
2.解决办法
程序在一轮输入结束与第二轮输入开始之间的所有换行符和空格都会导致问题,因此我们也要在一轮输入后过滤到所有的空白符;采用同样的方法——while循环丢弃两轮之间的输入。
三、输入验证——创建更友好的用户界面
1.原因
在实际应用过程中,用户除了输入我们期望的输入之外,还会有其他的错误,我们要事先预料到一些可能的输入错误。
2.解决办法
①不匹配的错误
在第一个问题中,我们要求用户输入y/n,用户也可以输入其他字母,我们可以用if语句筛选其他应用。
②某些范围错误
1.某一个程序需要非负整数的循环,但是用户可能输入一个负数或者非整数,可以用关系表达式排除这种情况:
2.用户输入范围不在指定范围内
同样可以用if语句进行筛选(可以使用一个布尔类型结果)
通过函数的结果来进行if条件的判断。
程序越大,越要使用模块化编程(独立函数来验证输入输出和管理)
四、应用——菜单浏览
需求:菜单需要获取用户的响应,根据不同相应执行相应的动作,此外,还需要提供返回菜单的选项(循环输入或者退出)。
实现: 对于上述提到的 缓存输入或者混合字符输入问题,我们可以编写不同的函数来执行。如下所示
#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
#include<stdbool.h>
char Get_choice();
char Get_first();
void count();
//---------------------menu程序-----------------
int main(void)
{
char choice;
while( (choice = Get_choice()) != 'q')// Get_choice 里对输入进行选择和判断,同时输出菜单
// 退出菜单不进入switch
switch (choice)
{
case 'a': printf("Buy low,sell high.\n");
break;
case 'b': printf("\a");
break;
case 'c':count(); //计数程序
break;
default:printf("Program error.\n");
}
printf("Bye.\n");
return 0;
}
char Get_choice()// 显示菜单 并且对输入进行判断
{
printf("Enter the letter of your choice:\n");
printf("a.advice b.bell\n");
printf("c.count q.quit\n");
char user;
user = Get_first();
while ((user<'a' || user>'c') && user != 'q') //先考虑不满足输入的情况
{
printf("Please respond with a,b,or q.\n");
user = Get_first();
}
return user;
}
char Get_first() //提取每行输入的第一个字符,排除了缓冲输入的影响
{
char start;
start = getchar();
while (getchar() != '\n')
continue;
return start;
}
void count()//技术程序
{
int i;
char ch;
printf("Count how far?Enter an integer:\n");
if (scanf("%d", &i) != 1) //对输入进行判断,先考虑不满足输入的情况
{
while (ch = getchar() != '\n')
putchar(ch);
printf("is not an integer.\n");
printf("Please enter an integer value,such as 25,-178,or 3:");
}
else
{
for (int j = 1; j <= i; j++)
printf("%d\n", j);
}
}