缓冲区到底是什么?程序总是出人意料!

发布时间:2023年12月20日

缓冲区

用户输入的字符后立即重复打印该字符是属于无缓冲(或直接)输入,即正在等待的程序可立即使用输入的字符。
系统在用户按下 Enter键之前不会重复打印刚输入的字符,这种输入形式属于缓冲输入
用户输入的字符被收集并储存在一个被称为缓冲区(buffer)的临时存储区,按下Enter"键后,程序才可使用用户输入的字符。缓冲区的大小取决于系统,常见的大小是512字节和4096字节。
在这里插入图片描述
缓冲分为两类:完全缓冲IO和行缓冲IO。

  • 完全缓冲输入指的是当缓冲区被填满时才刷新缓冲区(内容被发送至目的地),通常出现在文件输入中
  • 行缓冲IO指的是在出现换行符时刷新缓冲区。键盘输入通常是行缓冲输入,所以在按下Enter键后才刷新缓冲区。

getchar()和putchar()

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;
}

在这里插入图片描述

文章来源:https://blog.csdn.net/qq_57570560/article/details/132747685
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。