带你理解输入输出缓存区(超详解)

C语言简介之 输出缓冲区、输入缓冲区 输出缓冲区:    程序并不会立即把输出的数据显示到屏幕上,而是先存储在输出缓冲区中,当满足一定条件时才显示出来    1、遇到\n    2、程序结束          #include <unistd.h> sleep(3);    3、遇到输入语句    4、当缓冲区满4k时    5、fflush(stdout) 手动刷新    缓存区机制可以提高数据的读写速度,并且可以让低速的输入输出设备与高速的CPU之间协调工作 输入缓冲区:    程序 阅读详情
AI摘要

缓冲区是内存中用于暂存输入输出数据的部分,分为输入缓冲区和输出缓冲区。完全缓冲在数据填满后才刷新,无缓冲则不缓存直接操作,行缓冲在遇到换行时刷新。printf和scanf等函数涉及到行缓冲,scanf会吃掉回车。_getch函数则是不带缓冲的输入函数,直接读取键盘输入。

带你理解输入输出缓冲区(超详解)

1.缓冲区的意义

缓冲区(Buffer)是内存空间的一部分。也就是说,在内存中预留了一定的存储空间,用来暂时保存输入或输出的数据,这部分预留的空间就叫做缓冲区。缓冲区根据其对应的是输入设备还是输出设备,分为输入缓冲区和输出缓冲区。

举个例子,相信大家在洗衣服的时候往往不会有了一件旧衣服就马上拿去洗衣机洗了,而等多几件了之后一起洗,这还可以避免水电资源浪费。同理,计算机的缓存区也是运用了同样的思想。
简而言之,缓存区就是一块内存,用来做数据的临时存放点,在输入输出操作者起至关重要的作用

2.缓冲的分类

1.完全缓冲

就是等整个缓存区被填满,才会被刷新缓存。最典型的例子就是磁盘的文件,文件用标准IO打开,默认都是全缓存。当缓存区填满或进行flush操作时才进行磁盘操作。

比如内存中有一段存储区域,比如有64个字节大小,有一个程序会从这段存储区域中读取数据。系统把一个文件内容放入这个区域,只要64个字节都放满了,那么程序会立即来读取这64个字节的数据。只要64个字节没有放满,哪怕只放了63个字节,程序都不会来读取,这就是完全缓冲的意思。

2.无缓冲

不对输入输出操作进行缓存,对流的读写可以立即操作实际文件。标准出错情况stderr是典型代表,这使得出错信息可以直接尽快地显示出来.

3.行缓冲

即当一行结束的时候便开始刷新缓存.想要刷新行缓存,只要使用换行符’\n’便成功,即回车键(enter),其中我们最常见的也就是输入输出缓冲(printf,scanf)就是行缓冲.(这也是我们今天的重点!!!)

补充:如果我们没有自己设置缓冲区的话,系统会默认为标准输入输出设置一个缓冲区,这个缓冲区的大小通常是 512个字节 的大小。缓冲区大小由 stdio.h 头文件中的宏 BUFSIZ 定义
在这里插入图片描述

接下来我们着重讲一下我们最常接触到的输入输出缓冲(行缓冲)

3.1输出缓冲区

在C语言中很多输出函数(如printf, putchar)便存在输出缓存. 在window系统下,使用printf()函数后,数据被写入到输出缓冲区,随后立即刷新缓冲区,所有我们在使用printf()函数时往往会很快就在控制台打印出来了(Linux操作系统略有不同,在此我们便不做演示)

3.2输入缓冲区

类似于输出函数,输入函数(scanf,getchar)也存在输入缓存,并且这些输入函数属于阻塞函数,当缓存区没有内容时,程序将阻塞在输入函数中,等待用户从键盘输入内容,并按下回车键(即换行’\n’)确认,之后,输入的字符将进入输入缓存区,输入函数便从缓存区获取字符,并且删除缓冲区中已经获得的字符,并解除阻塞状态继续执行代码

下面举例一个十分经典的C语言代码来展示输入缓存的存在

#include<stdio.h>
int main()
{
	char str[10];
	int i;
	for(i=0;i<10;i++)
		scanf("%c",&str[i]);        
	for(i=0;i<10;i++)
		printf("%c",str[i]);
	return 0;
}

上面这个程序,获取10个字符,然后打印出来,如果我们正常的输入10个字符,打印正常
在这里插入图片描述
但是如下程序,如果我们输入a,然后回车,再输入b,再回车… 结果只能输入5个字符便打印了出来程序结束,这其实就是所谓的scanf() 吃掉回车
在这里插入图片描述
分析:首先这个程序运行到第1次循环的scanf的时候,此时缓冲区为空,即发生阻塞现象,我们输入a,之后按回车,此时缓存区其实是两个字符,‘a’和’\n’,然后此时的scanf拿到了字符a,第一次循环结束(注意此时缓存区还剩一个’\n’). 开始第2次循环. 但是scanf发现缓冲区有’\n’,便不会发生阻塞,此时scanf读取这个’\n’. 然后又开始第三次循环,此时缓冲区是空的,便又发生阻塞,所以又等待键盘输入,我们输入b,再次按下回车,此时缓存区又是两个字符,‘b’和’\n’,接下来重复上面过程.综上,相当于这个循环十次的for循环在第偶数次得到的都是’\n’,这也是为什么后面打印的时候这abcde是竖着打印出来的

3.不带缓冲的输入函数

前面介绍了带缓存的输入函数,只有当按下了回车键之后,输入的字符串才能进入缓存区,等待程序读取。接下来介绍一个不带缓存的输入函数( _getch ),只要按下键盘,程序立即获得输入的字符串。_getch直接从键盘获取键值,不等待用户按回车,只要用户按一个键,_getch就立刻结束输入了,换言之,不需要将输入的字符保存在缓存区,也就是说,输入一个字符,它马上读取

#include<stdio.h>
#include<conio.h>
int main()
{
	while (1)
	{
		char c;
		c = _getch();   //输入后用putchar打印
		putchar(c);
		if ('q' == c)
			break;
	}
	return 0;
}

输入“abcq”,程序立即显示‘abcq’并退出,如下
在这里插入图片描述
这是因为_getch相当于无缓存的getchar(或者单个读取的sancf函数),程序运行到_getch函数将进入阻塞状态,并等待键盘直接输入一个字符,按下一个键后(不需要回车送入输入缓存区),getch函数就立刻能收到对应的字符(但是不会显示在控制台上),随后通过putchar打印在控制台。简而言之,这是一个不带回显的函数,即控制台abcq完全是putchar的功能,_getchar是不会显示内容的(不带回显),所以这个函数可以应用在密码中

接下来对比如果换成scanf控制台结果.

#include<stdio.h>
#include<conio.h>
int main()
{
	while (1)
	{
		char c;
		scanf("%c",&c);   //输入后用putchar打印
		putchar(c);
		if ('q' == c)
			break;
	}
	return 0;
}

打印出的结果为:
在这里插入图片描述

此时有两排,因为scanf是带回显的,第一排是键盘输入,第二排才是打印的。
相当于上面_getch打印出来的abcq是没有第一排的,只有第二排。

一文带你深入浅出C语言输入输出与缓冲 本文主要讲讲C语言中的输入输出函数以及缓冲区的一些知识,读者最好有一点C语言基础。由于作者水平问题,难免会有纰漏,各取所需就好。 阅读详情

相关推荐

锁存器、触发器、寄存器和缓冲器的区别

比如现在用一个clk接到latch的使能端(假设是高电平使能),这样需要的setup时间,就是数据在时钟的下降沿之前需要的时间,但是如果是一个DFF,那么setup时间就是在时钟的上升沿需要的时间。锁存器的输出对输入透明的,输入是什么,输出就是什么,这就是锁存器不稳定的原因,而触发器是由两个锁存器构成的一个主从触发器,输出对输入是不透明的,必须在时钟的上升/下降沿才会将输入体现到输出,所以能够消除输入的毛刺信号。常见的锁存器包括SR锁存器、D锁存器和JK锁存器,它们的差别主要在于触发方式和输出结果的不同。

weixin_50518899的博客 2462

输入缓冲区

输入缓冲区:这是一个我们键盘输入与编译器读取之间的一个缓冲区域,编译器并不是直接读取我们在键盘上输入的信息,而是从输入缓冲区中读取的信息。我们使用scanf、getchar等输入函数时,并不是直接从键盘中去获取,而是由键盘打到输入缓冲区中,然后scanf,getchar等输入函数再从输入缓冲区里面去获取数据。

weixin_73914025的博客 2936

FIFO缓存区设计

目录 1.缓存区的制作 2 改善上述缓存区 3 缓存区的实现 1.FIFO (First Input First Output)一种先进先出的数据缓存器,先进入的数据先从FIFO缓存器中读出,与RAM相比没有外部读写地址线,使用比较简单,但只能顺序写入数据,顺序的读出数据,不能像普通存储器那样可以由地址线决定读取或写入某个指定的地址。 2.FIFO一般用于不同时钟域之间的数据传输,比如FIFO的一端是AD数据采集,另一端为PCI总线,那么在两个不同的时钟域间就可以采用FIFO来作为数据缓冲。另外.

qq_41687938的博客 5421

TCP缓存区与窗口的关系

TCP缓存区与窗口关系网上大多错误的理解 滑动窗口大小=接受缓存区大小 接收方通告窗口大小=发送方缓存区大小 注意:以上两个结论都是错误的我们在学习网络编程时,通常会参考两本很经典的书《UNIX网络编程 卷1》和《TCP/IP 卷1》。然而,我在看与缓存区与窗口相关模块知识点时,通常会犯迷糊。感觉这两本书对其的描述很少,描述得有点模糊。《TCP/IP详解 卷1》第1版的一句重要的描述,因为在小字处

yxccc的博客 1万+

python中的关于刷新缓存区flush的问题

flush是缓存区的意思,你的输入输出一般并不会直接输入输出,而是存在一个叫做缓存区的地方 以标准输入输出中的先来举例,对于标准输入输出中的显示,在你键盘输入内容之后,内容并不会立即显示到显示器,而会存储到缓存区中,除非 flush的缓存已经满了,它会自动输出 遇到换行符 程序被终止 比如 import time for i in range(5): print(i) time.slee...

pjliyuhang的博客 3966

csapp lab3 bufbomb 缓存区溢出攻击 《深入理解计算机系统》

这个实验主要是熟悉栈,和了解数据缓存区溢出的问题。 数据缓存区溢出:程序每次调用函数时,会把当前的eip指针保存在栈里面,作为被调用函数返回时的程序指针。在被调用程序里面,栈是向下增长的。所有局部变量都存储在栈里面(静态局部变量除外)。假设有一个字符串变量str,在str读取数据时,如果缓存区没有进行一定的保护,会造成缓存区的溢出。由于栈是向下增长的,但是对于一个变量,如str,他的数据存储顺序

fang92的专栏 5299

c语言清除文件缓存区,C语言之清空缓存区

在C语言中,我们常常需要去清空缓存区,对于缓存区清空的重要性,接下来我们进行具体的说明。首先我们先解释一下缓存区。1.缓存区C语言中的缓冲区又称为缓存,它是内存空间的一部分。也就是说,在内存空间中预留了一定的存储空间,这些存储空间用来缓冲输入或输出的数据,这部分预留的空间就叫做缓冲区。C语缓冲区分为三种类型:1、全缓冲 2、行缓冲 3、不带缓冲。缓冲区根据其对应的是输入设备还是输出设备,分为输入缓...

weixin_39652154的博客 5406

一文带你读懂C/C++语言输入输出流与缓存区

关注、星标公众号,直达精彩内容ID:技术让梦想更伟大作者:李肖遥前言有没有发现,基本上所有的C语言入门书籍,或者是我们的教程里面,第一个C语言程序实体,都是“Hello Word!”;我...

李肖遥的专栏 909

Socket清空缓存区

情况一:知晓缓存区中数据的大小 这种情况应该就不用多说了,直接循环的把数据都读取出来就行了。 情况二:不知道缓存区中数据的大小 方案一 close一次socket,这个方案有效是有效,但这样的小问题还不至于如此大动干戈,因此不建议使用。 方案二 使用recv来读取,但是在阻塞模式下效率低下,因为在不知道数据的情况下,在最后一次读取的情况下需要等待到超时才会知道数据是否读取完毕。 方案三 使用fg...

姑苏流白 2万+

一步一步搭建S32K14x的AutoSar项目----MCAL工程创建及说明

一步一步搭建S32K14X的Autosar项目--MCAL工程创建及说明

wo580231的博客 2494

Cadence17.4 Allegro PCB制板(gerber / 光绘)文件输出的顺序及注意点

Cadence Allegro PCB制板文件输出 (gerber 光绘文件输出)

weixin_45331044的博客 1万+

getchar函数与其在缓存区的使用(详解易懂)---读取多组值:scanf返回值的理解使用

本篇是在题中如何使用EOF作为判断条件,进行多组输入的,在习题中体会getchar在缓冲区中的使用,如有错误,请在评论区指正,让我们共同进步!

m0_69119792的博客 674

《iOS之一起进大厂》系列-秒杀面试官的RunLoop底层原理面试题

Runloop是iOS面试中的必考题,不管大厂小厂都会问到。 这里包括了Runloop几乎所有的面试题,还有中肯完整的答案解释。

空杯子 1153

关于ROS消息缓存区的存取理解

1、spinOnce不是指执行一次callback,而是执行当前缓存区中msg的数量。 2、callback取的是缓存区队列中最早接收的数据。 3、callback缓存区是先进先出的队列格式。

qq_35189442的博客 1502

告别“静态组件”:Adobe XD的堆栈+状态,打造“活”的响应式UI

今天,我想分享一套能彻底告别这种“笨方法”的、Adobe XD中的进阶技巧,通过组合使用“堆栈”、“内边距”和“组件状态”,去构建一个能自动适应内容、真正“活”起来的智能响应式组件。

Kingsdesigner的博客 762

HexView 脚本自动化工具:从刷写文件处理到批量转换实战

本文详细介绍了如何利用HexView脚本自动化工具高效处理嵌入式刷写文件。通过实战演示,文章展示了如何使用bat脚本实现S19、HEX等格式文件的剪切、填充、合并与批量转换,构建自动化流水线,从而显著提升汽车电子等领域的开发与生产效率。

weixin_29237635的博客 356

C语言基础之输入输出

本次博客会是最有料的博客了,这其中的问题尤其是scanf函数对新手很不友好我们本次1会讲解其他的一些输入输出函数,分析他们的优劣点2本次的参考资料来自于它的参数先不讲,但是它的返回值得有讲头我们看看他的返回值是个啥scanf返回成功转换和分配的字段数;返回值不包括已读取但未分配的字段。返回值0表示未分配任何字段。如果在第一次尝试读取字符时遇到文件结尾字符或字符串结尾字符,则返回值为EOF。那么这里又有一个问题了,scanf函数是如何读取的呢我们来给大家总结一波1 输入输出是存在缓存区的。

comeonworld的博客 1318

FOC 转子初始位置检测(图文详解)

什么是转子的初始位置? 其实转子的初始位置是不确定的,但是在电机启动的时候,我们需要得到电角度,这样才可以进行矢量控制;所以,这里将转子与A轴重合作为初始位置,此时电角度也恰好为零,具体如下图所示; ) 至于原理下面会详细分析,这样在转子到初始位置后,也可以得到准确的电角度,就可以实现磁场和转子的同步转动。 如何让转子运行到初始位置? 其实这是一个很简单的问题,在这里我将它放大了,简单地分析了一...

一名热爱技术的工程师的博客。分享技术干货,记录美好生活。永远相信美好的事情即将发生。 2万+

清除缓存区的错误数据

处理非法数据 常常用于清除缓存区的字符的语法 while(getchar()!='\n');/*清除缓存区的非法字符*/ fflush(stdin);/*清除缓存区的错误数据*/ 问题:输入两个整型数,计算并输出两个整数的最大值。如果用户不慎输入了非法字符,那么程序可提示“‘输入数据个数或格式错误” 这个简单程序就用到了fflush #include<stdio.h> main()...

qq_43490337的博客 3635

从原理到落地:Java+TensorRT打造YOLO模型GPU极致推理方案

Java+TensorRT的YOLO模型GPU加速方案,核心是通过JNI桥接实现Java与TensorRT的高效交互,结合TensorRT的底层优化能力,最大化GPU算力。该方案既保留了Java后端的工程化优势(如易维护、生态完善),又解决了AI模型推理的性能瓶颈,可落地于实时视频分析、智能监控、工业质检等场景。基于TensorRT Dynamic Shape实现多尺寸输入的自适应优化;结合Java的协程(Virtual Thread)提升异步推理的并发效率;

2601_94871597的博客 766

AI测试:手把手教你用AI做Web自动化测试「喂饭教程」

本文介绍了基于MCP协议和使用 mcp-use + playwright-mcp 构建智能Web自动化测试框架的实践方法。通过整合大语言模型的理解能力与测试工具可靠性,该方案支持用自然语言描述测试流程,自动转换为可执行的测试步骤,提升测试效率,支持复杂场景和多步骤流程,为自动化测试提供了新思路。

blues_C的博客 1283

关于缓存区

c语言里面的stdio.h库函数里涉及到了缓存区,具体案例是这样的:#include struct{ char name[32]; int age; char sex; }user; int main(int argc, const char *argv[]) { printf("enter user's name ,age,sex:\n"); scanf("%s%d%c",user.n

DRJsportman的博客 870

温度PID控制PLC程序

温度PID稳定控制程序,适用于欧姆龙PLC,对其他PLC也具有很大参考价值

<C语言>| 关于scanf读取缓存区的理解

文章目录前言scanf函数的定义:功能:执行格式化输入总结解决方法 前言 在牛客做了很多坑爹的题,明明代码没问题但是就退无法AC,看了很多题解之后,发现是scanf读取缓存区,在输入输出时出现了问题 于是写个博客总结一下 首先我们要了解什么是 scanf 函数 根据 cplusplus.com的解释 scanf函数的定义: scanf()函数是通用 终端格式化输入 函数,它从标准输入设备(键盘) 读取输入的信息。可以读入任何固有类型的数据并自动把数值变换成适当的机内格式。 其调用格式为: scanf(

GuLeng______的博客 1813

win10 跳过U8环境检测的IE WebControls.rar

win10 安装u8的时候 提示IE WebControls 不通过,这个工具可以欺骗u8的检查。 跳过U8环境检测的IE WebControls。提示导入失败后,重新检测通过。

Camera2Demo

在Camera2 的基础上进行封装,使得Camera2一堆初始化逻辑与Activity分离,降低耦合度,完成预览拍照并保存的操作

java 缓存区_Java NIO--基础理论之缓存区

1、概述:NIO我的理解就是 New IO,是API1.4里提供的新的API,为所有的原始类型做缓存支持。NIO主要的核心组成部分:Buffer(缓存)Channels(通道)Selectors(选择器)2、缓存区描述:一个用于特定基本类型数据的容器。缓冲区是特定基本类型(除了布尔型)元素的线性有限序列。除了内容之外,缓存区还具有容量、位置和界限。容量:是缓存区所包含的元素的数量。缓冲区的容量不能...

weixin_39983223的博客 213

文档:亲测可用解决vnc灰屏,黑屏,鼠标大黑叉情况

主要解决vnc-viewer灰屏,黑屏,鼠标大黑叉等现象,详细见文档。

上一篇: C语言中的%2d,%02d,%-2d的含义,以及解决99乘法表打印不对齐问题
下一篇: 指针和指针变量有何不同,为何混而一谈(根本是左值右值的区别)
kklovecode
博客等级 码龄4年 127粉丝 29原创
评论 16
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

kklovecode

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值