三.几种常见错误详解
1.不理解原理导致的错误
下面以getchar为例具体讲解一下这种错误的产生及解决方法
代码如下:
#include<stdio.h> int main() { char password[20] = {0}; printf("请输入密码:"); scanf("%s", password);//以字符串的形式输入 printf("请确认密码(Y/N):>");//用户输入Y/N确认 int ch = getchar(); if (ch == 'Y') { printf("确认成功\n"); } else { printf("确认失败\n"); } return 0; }
来看看这段代码运行的结果
嗯?什么情况,我还没输入Y或N怎么就确认失败了??
好了,这里我就不卖关子了。
scanf和getchar这两个输入函数,它们都是从键盘上得到我们的数据,而不是直接从键盘上来读取我们的数据。它们和键盘之间有一个区域叫输入缓冲区。所有输入的数据都会先放在输入缓冲区中。
在存放输入的数据时,输入函数先来看看输入缓冲区中是否有数据,如果有,它就直接拿走并储存,而不需要从键盘再输入数据,如果输入缓冲区中什么都没有,则需要从键盘输入,再拿走。
带入上面的代码试试
当我们输入123456时,为了把“123456”放进去,其实还敲了一个回车,因此实际上输入缓冲区中存放的是“123456\n”。
程序继续运行,此时它把“123456”提取出来,输入缓冲区中还留有一个“\n”.
注意:
程序走到这一步后,进行第二次从键盘中读取( int ch = getchar() ),此时输入缓冲区中还滞留有上次未提前出来的“\n”,因此不再从键盘上读取数据,直接把“\n”从输入缓冲区提取出来。此时ch的地址中存放的就是“\n”,显然不等于’Y’,所以输出为“确认失败”
看了上面的讲解,你弄懂了吗?接下来我们来讲讲改进方法
其实改进很简单,它不是在输入缓冲区中还滞留有“\n”吗?我再使用一个输入函数把它给读走不就行啦?
int main() { char password[20] = { 0 }; printf("请输入密码:"); scanf("%s", password); printf("请确认密码(Y/N):>"); getchar();//把多余的\n取走 int ch = getchar(); if (ch == 'Y') { printf("确认成功\n"); } else { printf("确认失败\n"); } return 0; }
这种方法雀氏可行,但是如果这样呢?
请输入密码:12345 6(中间加空格)
?怎么又这样了??我不是把“\n”读走了吗?
解释亿下:
此时输入缓冲区中是这样的。
轮到scanf来取缓冲区中的数据,当它读到空格的时候,它就不再继续往下读了(这是scanf的一个作用性质)。
所以scanf就只取走了12345,而缓冲区中还剩下(空格)6\n。
此时,getchar()读取一个字符,它把空格给读走了,输入缓冲区中剩下6\n.
最后,int ch = getchar()把6给读走,不等于’Y’,于是打印“确认失败”
难道没有什么办法避免这种错误吗?
什么话,没有办法我会把这种错误写出来吗??这不是自己打自己脸吗?
解决方案
介于输入缓冲区中一直存放有数据未被清理,我们需要把缓冲区中多余的数据先全部清走。
方式:
采用一个循环,只要没读到\n,我们就一直用getchar读。
代码实现如下:
#include<stdio.h> int main() { char password[20] = {0}; printf("请输入密码:"); scanf("%s", password); while ( getchar() != '\n');//把缓冲区中多余的内容全读走,直到\n停止 printf("请确认密码(Y/N):>"); int ch = getchar(); if (ch == 'Y') { printf("确认成功\n"); } else { printf("确认失败\n"); } return 0; }
结果:
完美解决
2.输入参数不符合输入控制符要求
比如以下代码:
# include <stdio.h> int main(void) { char m; int n; scanf("%c%d", &m); printf("m = %c, n = %d\n", m, n); return 0; }
不做过多解释,scanf中输入控制符要求你输入两个数据,结果你的输入参数只输入了一个,你觉得这可能正确吗?
但其实对于多组输入来说,不输入正确个数的数据也有一定意义,详情可以看看我的这篇博客:关于C语言中scanf多组输入的实现
需要注意的是:
一但发生这种错误时,编译器可能并不会报错,但是从程序上来说它是绝对错误的,当发现异常时,一定要多多注意认真检查一下输入函数。
总结
以上就是今天要讲的所有内容啦
有任何疑问欢迎在评论区或者私信博主指出哦。
大噶(家)下次见啦!
如果感觉有帮助的话不妨三连一下这个新人博主。你们的支持就是我更新的动力。
(可莉请求你们三连支持一下博主!!!点击下方评论点赞收藏帮帮可莉吧)