缓冲区,缓存,fflush(stdin)如何使用?

简介: 缓冲区,缓存,fflush(stdin)如何使用?

本人也是初步学习缓冲区问题,如下面有不正确或者表达不当的地方还请大佬在评论区斧正!!!

对初学者来说fflush(stdin)被解释为清除输入缓存但在不同的时期它的作用也在不断淘汰。

缓冲区问题也能困扰了不少c语言小白或者一些人学习的脚步,那什么是缓冲区,缓存,以及怎么结决这些问题呢?那我一一给大家介绍,基础懂了就懂了其中的原理(博主可能会发布新的关于缓冲的问题或者其他问题的观点所以给波关注不迷路!!!)

我们将以以下代码作为实例

image.png编辑

一、什么是缓冲区

缓冲区又称为缓存,它是内存空间的一部分。也就是说,在内存空间中预留了一定的存储空间,这些存储空间用来缓冲输入或输出的数据,这部分预留的空间就叫做缓冲区。

缓冲区根据其对应的是输入设备还是输出设备,分为输入缓冲区和输出缓冲区。

image.png

比如图中蓝色是我们a的内存空间,红色是随机的缓存空间。

二、为什么要引入缓冲区

我们为什么要引入缓冲区呢?

image.png

编辑

我们先把读出的数据放在缓冲区,计算机再直接从缓冲区中取数据,等缓冲区的数据取完后再去磁盘中读取,这样就可以减少磁盘的读写次数,再加上计算机对缓冲区的操作大大快于对磁盘的操作,故应用缓冲区可大大提高计算机的运行速度。就像是买房者,中介,和卖方者的关系,可以让交易进行的更快更和谐。

缓冲区就是一块内存区,它用在输入输出设备和CPU之间,用来缓存数据。它使得低速的输入输出设备和高速的CPU能够协调工作,避免低速的输入输出设备占用CPU,解放出CPU,使其能够高效率工作。

缓冲区分为三种类型:全缓冲、行缓冲和不带缓冲。

1、全缓冲

在这种情况下,当填满标准I/O缓存后才进行实际I/O操作。全缓冲的典型代表是对磁盘文件的读写。

2、行缓冲

在这种情况下,当在输入和输出中遇到换行符时,执行真正的I/O操作。这时,我们输入的字符先存放在缓冲区,等按下回车键换行时才进行实际的I/O操作。典型代表是键盘输入数据。

3、不带缓冲

也就是不进行缓冲,标准出错情况stderr是典型代表,这使得出错信息可以直接尽快地显示出来。

现在应该初步了解什么是缓冲区,以及缓冲的作用了吧,下面我们粗说fflush(stdin):

历史我们不要过于深究,大概了解下,它在vs 2013之前的版本以及vc++6.0可以正常使用但是在vs 2015环境下fflush(stdin)不再起作用(使用rewind(stdin)解决)

如果我们运行案例代码,输入类型不同结果如下

image.png

编辑

产生原因:在正常情况下,读取时输入缓冲区的内容会被scanf逐个取走,可以根据返回值判断成功读取走的数目。但在发生异常时,比如输入的类型不同读取发生异常,这时输入缓冲区的内容也就是不同类型的内容未被取走,在下次循环时自动从缓冲区中输入到scanf中,不再等待user输入,以至于scanf的返回值一直是0!=EOF,(EOF是一个宏,具体值时-1),进行死循环。(这不能怪缓存,更不能怪编译器,虽然他不会判断内容是否合法!)(这是输入缓冲区出现问题)

如何解决呢?

我们使用scanf(“%*[^\n]%*c)可以很有效的解决这个问题

image.png编辑

让我们看看效果如何

image.png编译

完美运行!

那怎么理解scanf("%*[^\n]%c") 呢?%[^\n]是逐个读取缓冲区’\n‘之前的内容,第一个%后的是丢弃掉这些内容,所以还有\n没有丢弃,我们再用%*c丢弃'\n',两者结合就可以清除掉缓冲区内容,再输入内容。

以上就是我对缓冲区的理解了,可能解决缓冲区的问题不止这一种,如果大佬们还有新的办法请在评论区留言,点赞鼓励一!!!

相关文章
|
19天前
|
存储 缓存 固态存储
|
6月前
|
存储 缓存 监控
|
12月前
|
存储 缓存 Linux
如何在 Linux 中清空缓冲区和缓存内存?
如何在 Linux 中清空缓冲区和缓存内存?
573 0
如何在 Linux 中清空缓冲区和缓存内存?
|
存储 缓存 数据处理
缓存与缓冲区的区别
在计算机科学中,缓存(Cache)和缓冲区(Buffer)是两个常见的概念。尽管它们的功能有些相似,但它们在实际应用中具有不同的用途和工作原理。本文将介绍缓存和缓冲区之间的区别。
599 0
|
26天前
|
存储 缓存 NoSQL
数据的存储--Redis缓存存储(一)
数据的存储--Redis缓存存储(一)
60 1
|
26天前
|
存储 缓存 NoSQL
数据的存储--Redis缓存存储(二)
数据的存储--Redis缓存存储(二)
37 2
数据的存储--Redis缓存存储(二)
|
22天前
|
消息中间件 缓存 NoSQL
Redis 是一个高性能的键值对存储系统,常用于缓存、消息队列和会话管理等场景。
【10月更文挑战第4天】Redis 是一个高性能的键值对存储系统,常用于缓存、消息队列和会话管理等场景。随着数据增长,有时需要将 Redis 数据导出以进行分析、备份或迁移。本文详细介绍几种导出方法:1)使用 Redis 命令与重定向;2)利用 Redis 的 RDB 和 AOF 持久化功能;3)借助第三方工具如 `redis-dump`。每种方法均附有示例代码,帮助你轻松完成数据导出任务。无论数据量大小,总有一款适合你。
56 6
|
27天前
|
缓存 NoSQL 关系型数据库
redis和缓存及相关问题和解决办法 什么是缓存预热、缓存穿透、缓存雪崩、缓存击穿
本文深入探讨了Redis缓存的相关知识,包括缓存的概念、使用场景、可能出现的问题(缓存预热、缓存穿透、缓存雪崩、缓存击穿)及其解决方案。
127 0
redis和缓存及相关问题和解决办法 什么是缓存预热、缓存穿透、缓存雪崩、缓存击穿
|
2天前
|
存储 缓存 监控
利用 Redis 缓存特性避免缓存穿透的策略与方法
【10月更文挑战第23天】通过以上对利用 Redis 缓存特性避免缓存穿透的详细阐述,我们对这一策略有了更深入的理解。在实际应用中,我们需要根据具体情况灵活运用这些方法,并结合其他技术手段,共同保障系统的稳定和高效运行。同时,要不断关注 Redis 缓存特性的发展和变化,及时调整策略,以应对不断出现的新挑战。
21 10