1.前言
我们一般在进行输入输出的时候,就会用到 scanf / printf 。并且根据格式指定可以输入输出各种类型的数据。可以输入整形,字符,浮点型等其他类型的数据。
今天呢我先给大家再介绍一下 getchar 和 putchar.
2.getchar 和 putchar
getchar呢是读取一个字符,并且只能读取一个字符。putchar呢则是输出一个字符。
我们要学习getchar 和 putchar也很简单
- 首先getchar获取一个字符后会返回过来,我们就定义一个整形变量 ch 来接收它,然后再用putchar把接收的值打印出来即可。
int main()
{
int ch = getchar();
putchar(ch);
return 0;
}
- 可能有人会问 getchar返回类型为什么是 int 类型,不是 char 类型。
- 因为getchar读到字符后,它会把字符的ASCLL码值返回来。所以用整形接收。
- 还有一个点,getchar这个函数正常读取到字符的时候返回的是字符的ASCLL码值,但是它读取失败时返回的是 EOF,也就是 -1(整形)。整形的接收最好用int。ASCLL码的范围是 0 ~ 127
- 大家可以通过这个网站搜索各种函数cplusplus.com
3.缓冲区问题
3.1先观察一个代码
我们先来看一个代码:
这串代码的意思就是读取一个字符,然后输出一个字符。如果没有读取失败,就一直进行循环读取。 按ctrl+z即可停下来。
#include <stdio.h>
int main()
{
int ch = 0;
while ((ch = getchar()) != EOF)
{
putchar(ch);
}
return 0;
}
3.2输入缓冲区
上面这个代码看似很简单,其实逻辑是很复杂的。
我给大家介绍下它是怎样工作的:
- 当我们第一次运行的时候,它会等待让我们进行输入。
- 大家注意:像 getchar 和 scanf 是让我们输入数据的,但是这个输入数据是从键盘上拿吗?其实并不是。其实中间存在一个输入缓冲区。
- getchar 和 scanf 首先去看输入缓冲区中有没有东西存在。当我们第一次读取的时候去看输入缓冲区里没有东西,怎么办呢?这个时候就需要我们从键盘输入数据到我们的缓冲区里面。
- 第一次我们向输入缓冲区输入了一个A,并按下 回车键。回车其实就是 \n。第一次 getchar 把A读走,然后putchar把它输出。但是第二次进入循环,输入缓冲区中存在一个 \n,而 \n 不等于EOF,所以getchar就把 \n读走了,putchar 输出的时候就进行了一次换行。
3.3清除缓冲区
上面介绍的有什么用呢,其实它的用处还蛮多的。一般可以用来清空缓冲区。
看个代码:
- 这个代码就是让我们输入密码,并判断密码对不对。若密码正确,则输入Y。
int main()
{
printf("请输入密码:>");
char password[20] = { 0 };
scanf("%s", password);
printf("请确认密码(Y/N):>");
int ch = getchar();
if (ch == 'Y')
{
printf("确认成功\n");
}
else
{
printf("确认失败\n");
}
return 0;
}
- 我们先随便输入一个密码
我们发现,它并没有等我们确认密码就确认失败了。那这个代码哪里出了问题呢?
我们来一步一步分析
- 开始输入缓冲区是空的,我们输入一串密码到输入缓冲区,并按下回车。scanf 会将 \n 之前的字符都读取走。当 getchar 要读取字符的时候,由于输入缓冲区不为空,所以 getchar 就把 \n 给读取走了。所以直接就进行了判断,而 \n 又不等于 Y ,所以就确认失败了。
所以我们想正确的进行这个代码,是不是要在 scanf 输入之后将输入缓冲区清理掉。
- 怎么清理掉缓冲区呢?我们在 scanf 后面单独加一个 getchar 是不是就可以把 \n 读走呢?
我们发现确实可以了。当我们到这里的时候,可能有的同学就觉得他学会了,实际上还差一点,我们再测试一下:
我们发现又确认失败了,原因很简单,这一次缓冲区里面放的不仅仅是 \n 了。
- scanf 读取的时候默认的特点是读取到空格结束,scanf 把里面的123456读走了,第一个 getchar 把空格清理走了,但是缓冲区后面还放着 abc\n 呢,下一个 getchar 把 a 读走了,所以也确认失败。
- 我们发现一个 getchar 处理不完缓冲区的所有东西,所以我们可以写一个循环来清理缓冲区。当 getchar 读到的字符不等于 \n 我们就让它继续读。直到读取到 \n 我们就让它停止,这时缓冲区也就清理完毕了。
int main()
{
printf("请输入密码:>");
char password[20] = { 0 };
scanf("%s", password);
//清理缓冲区
while (getchar() != '\n')
{
;
}
printf("请确认密码(Y/N):>");
int ch = getchar();
if (ch == 'Y')
{
printf("确认成功\n");
}
else
{
printf("确认失败\n");
}
return 0;
}
注:也可以用 gets 和 scanf(“%[ ^ \n]”,str) 读取带空格的字符串,但是我们还是要弄懂缓冲区的原理。文章来源:https://www.toymoban.com/news/detail-454999.html
结尾
所以当以后大家做这种输入输出的时候很奇怪,怎么这个地方出问题了,怎么我还没有输入就停止了,这个时候我们就要学会去分析,是不是缓冲区出了问题。文章来源地址https://www.toymoban.com/news/detail-454999.html
到了这里,关于scanf老是出错?带你详细解决输入缓冲区问题的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!