Tips:本文主要面向C语言初学者及新手,属于系列文章,笔者借此巩固自身同时也希望帮助更多新人更快的入门,如有不当或错误,欢迎指正。
前言
前面文章我们介绍了C中常见的数据类型及基础的输入输出函数,本文主要是针对输入输出常见问题——垃圾字符的产生及解决方式展开,也会同时简单介绍下编程中的三大基本结构,属于基础内容,难度较低,建议速读了解掌握即可。
一、垃圾字符的产生
上一篇文章我们介绍了基本的输入输出函数printf(),scanf()等使用方法,现在我们来看下面这一段程序:
给a,b,c三个变量分别赋值并输出
#include <stdio.h>
int main(void)
{
char a,b,c;
printf("please input a:");
scanf("%c",&a);
printf("a=%c",a);
printf("please input b:");
scanf("%c",&b);
printf("b=%c\n",b);
printf("please input c:");
scanf("%c",&c);
printf("c=%c\n",c);
//上述代码中的输出均可使用getchar()替换
return 0;
}
按照我们的逻辑来看,理应是输出
但是事实上当我们运行完毕,发现执行的结果居然是这个样子:
这就是本文标题提及到的垃圾字符,此时这种情况便是产生了垃圾字符,影响到了我们的正常使用,读者不妨先思考下造成这种情况的原因是什么,接下来再继续进行讲解。
二、为什么会产生垃圾字符?
相信经过思考,有一些读者已经发觉了问题所在。当我们向终端输入数据时,按下回车的瞬间,我们的getchar()或者scanf(),实际获取的是上次残留的换行符\n,无法正确的获取到我们想要的字符。由此才导致了上文中举例产生的影响。
事实上,垃圾字符是比较常见的问题,但是不经意间的一点问题就有可能导致整个程序的崩溃错误或者轮询失败等大问题。以下情况是普遍易产生垃圾字符的情况,各位读者日后可以多加注意以下情况时的编程习惯:
1、使用scanf() 连续获取多个字符。
2、多个scanf()连续获取字符。
3、代码比较长,不确定前面有没有出现垃圾字符。
三、如何解决垃圾字符?
常见的垃圾字符回收方式有以下三种:
1.利用空格实现垃圾字符的回收
//只需要在使用scanf()函数时,控制格式的%c等字符前加上空格,即可实现垃圾字符的回收
char a,b,c;
printf("please input a:");
scanf(" %c",&a);
printf("a=%c\n",a);
printf("please input b:");
scanf(" %c",&b);
printf("b=%c\n",b);
printf("please input c:");
scanf(" %c",&c);
printf("c=%c\n",c);
实现效果如下:
该方式可以回收一个或多个的空格、回车、tab。
2.scanf()连续获取多个字符
该方式可以指定输入,但是使用起来较为繁琐。
3.使用getchar()函数回收垃圾字符
在每次使用完scanf函数后紧跟一个getchar()用以回收垃圾字符,该种方式一般只能回收任意一个字符,一般用于循环里面
while((getchar()!='\n'))
无论用户是输入多少个多余的字符,最后只能按一次回车。只要用户按回车,则回车之前的所有字符就都会被 getchar() 取出来,只要 getchar() 取出来的不是回车 ('\n') ,则表示用户输入尚未完成,用户按下回车输入完成,就会将输入的字符全部取完。
4.强制刷新缓冲区fflush()
在每次输入字符型数据之前,调用fflush(stdin)函数来强制刷新缓冲区
此处涉及到缓冲区及文件流部分知识,初学者可仅作了解,后续会讲解这部分知识,感兴趣的读者可以自行查询探索或等待后续讲解。
稍微深入来看,上述造成垃圾字符的原因是这样的:
scanf单字符输入时规定只接收一个字符,当我们输入更多的内容时,例如我们给a赋值时键盘上输入的是 1+回车 ,则1顺利传给了a,但是多余的回车带来的换行符 \n 却被遗留在了我们的缓冲区,再继续给b赋值时,我们又进行了一次 2+回车 的操作。从而造成 “b=” 后没有值,而且进行了一次换行的情况。
笔者习惯性的使用空格的方式吸收垃圾字符,诸位可自行探索自己习惯的方式用以解决垃圾字符。
四、编程的三大基本结构介绍
在C语言中有三大基本结构,分别是顺序结构、分支结构以及循环结构。
想象以下生活情景:
在自己卧室的你现在想要喝一杯热水,于是你执行了不同的步骤。
4.1顺序结构
顺序结构,顾名思义,就是按顺序执行的结构,代码依次从前往后逐步执行,没有任何的跳转,所有的语句都会被执行,直至程序执行结束 。该类结构的程序最为常见,可以说一个C中的程序即使不含有分支结构和循环结构,也必然会有顺序结构,因为程序只要执行,就是自上而下逐步顺序执行。
你要喝一杯热水,首先你要拿到自己的水杯,这是第一步。
第二步,便是烧水。
第三步,用杯子接热水。
成功喝到了热水,这就是顺序结构,一步一步执行下来。
4.2分支结构
分支结构,即为有分支。该类结构的特点就是依据某个变量的值或其他情况来进行判断,执行不同的程序。
还是喝热水这个情景,但是这个时候你发现水杯没有放在卧室,你需要去其他屋子里找到自己的杯子,于是你去了厨房、客厅、书房等房间寻找杯子,终于在书房找到。
第二步,烧水。
第三步,接热水。
成功喝到了热水
在这个时候,你第一次没有找到杯子于是去执行了其他的操作(去往其他房间寻找杯子),这就是分支结构。
常玩游戏的也可以理解为类似于“支线任务”,不影响你的主线体验。
4.3循环结构
循环结构,就是在达到指定条件前,重复执行某些语句。
仍然是喝热水的场景:
第一步,找杯子
第二步,烧水
第三步,接水
第四步,喝水
但是,你喝了一杯发现不解渴,于是你又喝了一杯,可是你还是觉得不解渴,继续又喝了一杯......直到你觉得不再口渴,你才停止了喝水的行为。
此时,刚刚你喝水的那部分便是 循环结构 ,而口渴,便是你执行“循环”的条件。
总结
至此,本文讲解结束,希望各位斧正,下一篇将会详细讲解三种基本结构在程序中的体现,例如if...else语句,switch语句,for循环等的介绍与使用。