用户输入的字符后立即重复打印该字符是属于无缓冲(或直接)输入,即正在等待的程序可立即使用输入的字符。
系统在用户按下 Enter键之前不会重复打印刚输入的字符,这种输入形式属于缓冲输入。
用户输入的字符被收集并储存在一个被称为缓冲区(buffer)的临时存储区,按下Enter"键后,程序才可使用用户输入的字符。缓冲区的大小取决于系统,常见的大小是512字节和4096字节。
缓冲分为两类:完全缓冲IO和行缓冲IO。
getchar ()和putchar()每次只处理一个字符。
getchar()读取每个字符,包括空格、制表符和换行符,这一点与scanf()显然不同。(一文搞懂scanf()读取字符)
putchar()打印字符
#include<stdio.h>
int main(){
int ch;
ch=getchar();
putchar(ch);
return 0;
}
看起来很简单?但是他执行的过程是什么呢?从键盘输入的数据直接赋值给了ch?错错错!!!如果是这样我们也不用介绍缓冲区了。
键盘输入的数据被放入了行缓冲区,这个时候getchar()会从缓冲区中读取我们刚才的输入,从缓冲区读走一个字符,相当于把这个字符从缓冲区里面清除,一次只读一个字符,赋值给了ch。
在使用输入的字符时,它也会给程序员带来麻烦。缓冲输入要求用户按下 Enter键发送输入,这一动作也传送了换行符,程序必须妥善处理这个换行符。
观察下面程序。用户选择一个数字,程序猜用户选中的数字是多少。关注的重点在输入和输出,假如我们选的数字是4,理想的程序输出如下
选择1-100内的整数,开始猜字。
如果我猜对恢复y,否则回复n
嗯...你的数字是 1?
n
数字是 2?
n
数字是 3?
n
数字是 4?
y
我知道我能猜到他!
#include <stdio.h>
int main(void)
{
int guess = 1;
printf("选择1-100内的整数,开始猜字。\n如果我猜对恢复y,否则回复n\n ");
printf("嗯...你的数字是 %d?\n", guess);
while (getchar() != 'y'){
printf(" 数字是 %d?\n", ++guess);
}
printf("我知道我能猜到他!\n");
return 0;
}
真正的输出结果如下
为什么会这样呢?
我们选择的数字是4。每次输入’n’时,程序打印了两条消息。每次从键盘输入的只是’n’字符吗?不是,每次从键盘输入的是字符’n’和换行符’\n’,输入到哪了?缓冲区!(键盘输入的数据被放入了行缓冲区)
getchar()时,由于程序读取’n’否定了数字1,还读取了一个换行符否定了数字2。(getchar()会从缓冲区中读取输入)
怎么解决呢?
使用while循环丢弃行缓冲区最后剩余的内容,包括换行符。
while (getchar() != 'y'){
printf("数字是 %d?\n", ++guess);
while(getchar()!='\n'){
continue;
}
}
continue是跳过当次循环,while(getchar()!=‘\n’)从缓冲区不断读取字符(从缓冲区读走一个字符,相当于把这个字符从缓冲区里面清除)直到读取到换行符,即while循环丢弃行缓冲区最后剩余的内容。
处理后的代码如下:
#include <stdio.h>
int main(void)
{
int guess = 1;
printf("选择1-100内的整数,开始猜字。\n如果我猜对恢复y,否则回复n\n");
printf("嗯...你的数字是 %d?\n", guess);
while (getchar() != 'y'){
printf("数字是 %d?\n", ++guess);
while(getchar()!='\n'){
continue;
}
}
printf("我知道我能猜到他!\n");
return 0;
}