目录
一、什么是getchar和putchar
我们知道scanf函数可以从键盘输入信息,而printf则可以输出信息,现在来看看下面的代码。同样地,getchar和putchar也有同样的功能。首先先来简单介绍一下:
getchar:顾名思义就是得到一个字符,也就是能在屏幕是输入一个字符。
putchar:它可以输出一个字符到屏幕上。
所以它两的作用是不是和scanf和printf函数一样呢?
让我们通过代码来看看:
#include <stdio.h>
int main()
{
// 输入
char ch = getchar();
// 输出字符
putchar(ch);
return 0;
}
【程序结果】
那么话说回来,scanf和printf可以针对各种各样类型的数据,比如整型、字符、浮点型都行,但注意:getchar和putchar只针对字符。
二、什么是EOF
#include <stdio.h>
int main()
{
char ch = 'a';
while ((ch = getchar()) != EOF)
{
putchar(ch);
}
return 0;
}
EOF全称是End Of File,是C语言标准库中表示文件结束符,它的值是-1。而getchar和scanf的返回值都是实际从键盘上得到数据的个数。也就是说,如果说getchar最后等于EOF,说明并没有从键盘上获取任何一个字符。
【程序结果】
三、getchar和putchar的应用场景及原理
设计一个输入密码的程序:
#include <stdio.h>
int main()
{
int password[100] = { 0 };
printf("请输入密码:>");
// 数组名是首元素地址,不用加&
scanf("%d", password);
printf("请确认密码(Y/N):>");
char ch = getchar();
if (ch == 'Y')
printf("确认成功\n");
else if (ch == 'N')
printf("确认失败\n");
else
printf("输入错误\n");
return 0;
}
【程序结果】
根据所学知识不难可以写出以上的代码,假设正确密码是“123456”,但是我还没确认密码直接跳出了确认失败,这是什么原因呢?
这就要说说其工作原理了
首先先执行scanf函数,我们在键盘上输入了“123456\n”,这些字符串是在缓冲区里的,由于scanf只会读取整型,于是就把“123456”拿走了,此时缓冲区还剩下\n,接着程序就来到请确认密码(Y/N),于是getchar就把\n拿走了,而\n又不等于‘Y’,于是就打印了确认失败。
接下来我们该如何解决这个问题呢?是不是只要在输入完密码后把\n消除就行了。
#include <stdio.h>
int main()
{
int password[100] = { 0 };
printf("请输入密码:>");
// 数组名是首元素地址,不用加&
scanf("%d", password);
//为了消除\n
getchar();
printf("请确认密码(Y/N):>");
char ch = getchar();
if (ch == 'Y')
printf("确认成功\n");
else if (ch == 'N')
printf("确认失败\n");
else
printf("输入错误\n");
return 0;
}
这里的getchar()就是为了消除缓冲区。你以为到这里就结束了吗?其实还没有...
假如现在问题复杂了,有的人可能会把密码输成123456 xxxx(6后面是空格)
程序还是出错了,还是一样的道理,此时缓冲区有“123456 xxx\n”,首先scanf还是把123456拿走了。此时还剩下一个“空格”和“xxx\n”, 而getchar一次只能读取一个字符,所以是不是写个循环问题就解决了。
#include <stdio.h>
int main()
{
int password[100] = { 0 };
printf("请输入密码:>");
// 数组名是首元素地址,不用加&
scanf("%d", password);
//为了消除\n
while (getchar() != '\n')
{
;
}
printf("请确认密码(Y/N):>");
char ch = getchar();
if (ch == 'Y')
printf("确认成功\n");
else if (ch == 'N')
printf("确认失败\n");
else
printf("输入错误\n");
return 0;
}
最后我来解释一下循环的条件,getchar读取了空格、xxx是不是都不等于\n为真。进入循环后啥也不干,就单纯把它们“吃掉”,最后读取到\n为假。跳出循环。