PS:一劳永逸的解决方案在3.4,但是我还是建议你从头看到尾。了解来龙去脉,彻底解决到编写C语言程序时,输入输出的顽疾。
一、C语言数据输入输出的弱点
C语言数据输入比较低级。因为C语言本身也不算一个正经八百的高级语言,它是一个中级语言,这体现在很多方面,比如它对底层硬件的操控能力,位运算等,又兼具高级语言的一些书写特点,类自然语言。再比如它的数据输入和输出语句格式繁琐,健壮性差(对数据类型要求严格,细致,对不同类型的异构数据输入的适应性差)。没有后来出现的高级语言的数据输入输出处理能力和集成度。
二、C语言能够处理的输入输出数据的类型
C语言能够处理的,输入输出数据的类型大体包括:整数,浮点数(小数),字符,字符串,文件流(从文件读入或输出到文件,包括文本或二进制数据)。常用的输入输出的函数包括:scanf, printf, getchar, putchar, gets, puts, fscanf, fprintf, fread, fwrite等。
三、初学者抓心挠肝的菜单输入问题
如果你得到一个任务,编写一个MIS系统(Management Information System),比如学生成绩管理系统,疫情信息管理系统等。这些MIS系统的最大特点是,处理字符或数值的数据,涉及到增删改查的基本数据操作。因此,往往需要编写一个能够循环显示并输入选项的菜单。
通常情况下,由于是控制台程序,没有鼠标,因此都是通过用户输入选项来完成菜单的选择的。用户从键盘输入选项,程序识别选项,并作出正确反映。
3.1程序员的思想误区
这里要留意的是:程序员往往会陷入一个误区,就是自己写的程序,使用者用起来都按照自己的思路来输入,他们忽略了,程序的使用者很大可能不是一个程序员,甚至可能是一个计算机小白,对于他们来说,不熟练或者忘记了你的输入忠告,而输入不合规的数据是很正常的事情。程序的健壮性也正体现于此,要求我们写出的程序能够正确处理所有可能的输入情况,做出正确的,合理的反应。
3.2菜单输入数据的可能性
用户在输入菜单的时候,会输入什么样的选项呢?通常情况下,C语言程序编写的菜单,主要允许用户输入整数或字符(字符串)。
3.3菜单输入可能出现的异常
3.3.1整数选项的输入异常
C语言输入整数需要使用格式化输入函数scanf。编写的菜单函数可能如下图:
如果用户输入的是aaa,那么就会产生异常
3.3.2字符选项的输入异常
如果采用字符作为选项,编写的菜单函数可能如下图:
当用户输入1回车的时候,程序也会出现异常。
出现这种异常的原因是:用户输入的1加回车,1被case1正确获取,并作出了回应。但回车被当做下一次循环的scanf的接收字符,显然,回车并不属于任何一个有效case。屏幕便打出了错误提示。
解决的方法有多种。
第一种,在每次循环结尾处,填上一句话,吃掉所有不是回车的字符,保证下一次循环不受影响。如图:
第二种,在输入的时候,%c前加上空格,表示吃掉所有白字符(看不见的字符,空格回车等)。如图:
但是上述解决方案,无法解决用户输入时的输入了123这种多余输入选项的情况,循环结构仍然会依次接受1,2,3三个字母,给出三次反应。显然,123本身的输入就是个无效的选项,系统给出正确反映并不符合我们的预期。
解决上述问题,需要再加上一条语句来清空输入的缓冲区。这样,程序在第一次接受了1以后,会清空输入缓冲区中的2和3。但是,这本身只能解决重复接收多余输入的尴尬局面,却没有根本上解决,用户输入123这种错误选项的问题,因为系统仍然识别为选项1.
3.4终极解决方案
上述的这些棘手的异常情况,可以通过字符串输入的方式一劳永逸的解决。
直接上代码,大家体会一下就明白了。
#include <stdio.h>
//菜单选项令人抓狂的输入问题
int main() {
char option[20];
int flag = 1;//flag为1表示一直在菜单循环状态,0表示退出菜单状态
while(flag == 1) {
system("cls");
printf("--------this is a menu-------\n");
printf("please enter your choice:");
gets(option);
if(strcmp(option, "1") == 0)
{
printf("function 1 was called.....\n");
}
else if(strcmp(option, "2") == 0)
{
printf("function 2 was called.....\n");
}
else if(strcmp(option, "3") == 0)
{
printf("function 3 was called.....\n");
}
else if(strcmp(option, "4") == 0)
{
printf("thank you for your operation....\n");
flag = 0;
}
else
{
printf("your input is error, please input an integer from 1 to 4...\n");
}
system("pause");
}
return 0;
}
四、总结
C语言的输入输出比较细致和繁琐,集成度不高,但也正是初学者了解程序设计基层逻辑的大好机会。作为典型的工科,同学们在学习编程的时候和学习木工,瓦匠没什么本质分别,除了勤学多练外,还需要积极总结经验,从最基础的基本功练起,高级语言如同组装的衣柜,如果开始就从那个高度学起,可能会很简单,按照说明书上的位置组装即可。但是你却不了解这些柜门,柜板是如何打造出来的。你将无法再随心所欲打造其他的衣柜了。
希望本篇对于受困于菜单的循环输入输出出现的各种异常问题的初学者能有所帮助。
视频讲解请关注:B站:猎风工作室崔老师