21-2 代码准备
getchar():获取字符
int ch = getchar(); //把获取的字符的ASCII码值放在ch中
int main()
{
int ch = getchar();
printf("%c\n", ch); //ch存的是该字符的ASCII码值,此处以字符形式打印ASCII码值对应的字符
putchar(ch);
}
运行结果:
第一行是输入的,二三行是输出的
注:EOF(end of file),读取错误或文件结束时,返回EOF
int main()
{
int ch = 0;
while ((ch = getchar()) != EOF)
{
putchar(ch);
}
return;
}
运行结果:
输入一个字符,按回车即可输出该字符;如果想要结束(即EOF),就按Ctrl+z
21-2 代码示例
写这样的代码有什么用呢?下面用一组例子向你展示
代码目的:输入密码->确认密码
//假如密码是字符串
int main()
{
char password[20] = { 0 };
printf("请输入密码:");
scanf("%s", password); //数组名本身就是地址
printf("请确认密码:");
int ret = getchar(); //键盘输入Y或N
if ('Y' == ret)
printf("Yes\n");
else
printf("No\n");
return 0;
}
假如我的密码是:abcdef,那么输入密码,敲一个回车:
奇怪!为什么我还没有输入Y/N,就显示No呢?
原因是:
scanf和getchar是同一类型的函数,它们不是直接从键盘上拿数据,而是从输入缓冲区里拿
输入密码:abcedf,按下回车(\n)scanf才能读到
scanf只拿按下回车前输入的密码,即abcdef
接下来getchar登场,它看到缓冲区里面还有个\n,就没等你输入Y/N就直接拿走了\n
此时,ret存的就是\n,自然不是'Y',所以进入else输出No
修改一下代码
思路:加一个getchar先把剩下的\n读取了
int main()
{
char password[20] = { 0 };
printf("请输入密码:");
scanf("%s", password); //数组名本身就是地址
getchar(); //读取'\n'
printf("请确认密码:");
int ret = getchar(); //键盘输入Y或N
if ('Y' == ret)
printf("Yes\n");
else
printf("No\n");
return 0;
}
依旧假如我的密码是:abcdef,那么输入密码,敲一个回车:
输入‘Y’确认密码,回车:
顺利执行了!但是这样就能解决所有情况吗?
假如我的密码是:abc def呢?
再次错误:
为什么呢?
原因:
输入密码:abc def,按下回车(\n)scanf才能读到
scanf读到空格前,即只读了abc
所以密码只读了abc
第一个getchar登场,此时还剩下 def\n,getchar只拿走' '(空格)
第二个getchar登场,此时还有def\n,直接读走一个字符,自然不是'Y',所以进入else输出No
综上,清除缓冲区的时候可能要清除的不是一个字符,而是一堆字符。所以我们直接搞一个循环,把所有的干扰字符都清除掉(清理缓存区):
int main()
{
char password[20] = { 0 };
printf("请输入密码:");
scanf("%s", password); //数组名本身就是地址
int ch = 0;
while ((ch = getchar())!= '\n')
{
;
}
printf("请确认密码:");
int ret = getchar(); //键盘输入Y或N
if ('Y' == ret)
printf("Yes\n");
else
printf("No\n");
return 0;
}
成功运行!