iostream 缓冲区详解(cin和cout)

C++ cout的使用,看这一篇就够了 1 C++输入输出综述 C++ IO首先建立在为Unix环境开发的原始库函数上;ANSI C正式承认这个库时,将其称为标准输入/输出包; IO相关类定义在头文件iostream和fstream,这些类不是正式语言定义的组成部分,cin,istream都不是关键字。 1.1 流和缓冲 (1)流简介: C++程序将输入和输出看作字符流;对于输入来说,程序从输入流中抽取字符,对于输出来说,程序向输出流中插入字符; 输入流可以来自键盘、存储设备或者其他程序;输出流可以输出至显示器、打印机、存储设备或者其他程序。 阅读详情

缓冲区

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

缓冲区的类型

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

  1、全缓冲

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

  2、行缓冲

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

  3、不带缓冲

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

缓冲区的刷新

下列情况会引发缓冲区的刷新:

  1、缓冲区满时

  2、执行flush语句

  3、执行endl语句

  4、关闭文件

cin和cout

cin和cout是C++中作为输入和输出的标准
cin是C++编程语言中的标准输入流对象,即istream类的对象,cin一般使用的是行缓冲机制,当输入接收到回车的时候就会进行数据的刷新,cin主要用于从标准输入读取数据,这里的标准输入,指的是终端的键盘
cout是流的对象,即ostream类的对象,这里的标准输出指的是命令行窗口

标准输入缓冲区

当我们从键盘输入字符串的时候需要敲一下回车键才能够将这个字符串送入到缓冲区中,那么敲入的这个回车键会被转换为一个换行符\n,这个换行符\n也会被存储在cin的缓冲区中并且被当成一个字符来计算!比如我们在键盘上敲下了123456这个字符串,然后敲一下回车键将这个字符串送入了缓冲区中,那么此时缓冲区中的字节个数是7
,而不是6。

cin读取数据也是从缓冲区中获取数据,缓冲区为空时,cin的成员函数会阻塞等待数据的到来,一旦缓冲区中有数据,就触发cin的成员函数去读取数据。

缓冲区和刷新

总所周知,要了解一个机制,最好的方法就是用一个实际的例子来进行说明
观察如下代码:
int a;
while (cin >> a) {
    cout << a <<endl;
}

对于如上的代码,当我们输入:1 2 3 4 5的时候,我们想要的也许是,输入一个处理一个

但是实际上在我们输入五个数字之后并敲下回车键,cout才一并将所有的五个数输出

在我们不了解的时候,我们也许会疑惑,就算是一次输出五个,那也应该是只进入一次循环吧,为什么在我们调用单步调试的时候,其实际上却进入了五次循环,a的值到底在哪里存储?cin的>>又在何时执行的?

要了解这些,我们首先应该知道,cin的>>运算符重载函数是阻塞式的,所以我们在输入:1 2 3 4 5的时候,while(cin>>a) 这个语句其实还没执行完

在我们输入换行符之前,我们实际上并没有对a进行任何的赋值,我们只是在缓冲区中构建了这样的一个数据结构(我的猜想):
这里写图片描述

在输入回车符之后,我们执行真正的>>运算符函数操作,如下:

  1. 根据这个数据结构将数据对应的变量进行赋值(赋值之前判断型别是否能够对应,不能的话,就将状态置为false)
  2. 赋值完毕,返回istream的引用
  3. 然后根据istream的operator bool()函数,返回流的状态是否正常,如果正常,返回true,然后进入循环。

输出a之后,再次进入刚才的>>函数中,由于缓冲区中还有数据没有读出,所以我们接着根据那个数据结构,一个个的将数据读出进a,并进行while的判断然后进入循环
读取完毕之后,cin的>>继续进入阻塞状态等待用户的输入
这就是一个完整的cin的输入流程

如何清空缓存区

从上文中可以想到,上一次的输入操作可能会导致缓冲区中的数据堆积,影响下一次的输入
,比如如下代码:

int main()
{

    int a;
    int i = 1;
    while (cin >> a) {
        cout << a <<endl;

        i++;
        if (i == 5)break;
    }
    char ch;
    cin >> ch;
    cout << "ch: " << ch;
    system("pause");
    return 0;
}

当我们输入1 2 3 4 5的时候,输出为:

1
2
3
4
ch: 5

可以看到,由于缓存区有残余数据,导致了其后ch的cin>>操作出现了错误,并且由于输入缓冲区未读取完,导致cin的条件状态也出现了错误。
所以我们应该使用clear()进行条件状态的复位,然后清空输入缓冲区:
函数原型:istream &ignore( streamsize num=1, int delim=EOF );
函数作用:跳过输入流中n个字符,或在遇到指定的终止字符时提前结束(此时跳过包括终止字符在内的若干字符)。
如下为示例:

int main()
{

    int a;
    int i = 1;
    while (cin >> a) {
        cout << a <<endl;
        i++;
        if (i == 5)break;
    }
    cin.clear();
    cin.ignore(numeric_limits<std::streamsize>::max(), '\n');
    char ch;
    cin >> ch;
    cout << "ch: " << ch;
    system("pause");
    return 0;
}

当我们再次输入:1 2 3 4 5,输出如下:

1
2
3
4
c
ch: c

可以看到,缓冲区的剩余数据被忽略掉了

C++输入输出流深度解析:从cin/cout到文件操作与错误处理实战 输入输出(I/O)是程序与外界交互的基础,在C++中通过流(Stream)抽象实现。其核心原理是利用运算符重载(如<<和>>)和缓冲区机制,提供类型安全的数椐传输。掌握C++ I/O的技术价值在于,它不仅是简单的语法,更是理解面向对象、资源管理等核心概念的窗口。在实际应用场景中,无论是控制台交互、文件读写还是数据解析,都离不开健壮的输入输出处理。本文以C++输入输出流为切入点,深入探讨了cin与cout的常见陷阱、输入验证方法以及文件操作技巧,并通过快递费计算器等实战案例,帮助开发者构建鲁棒的程序交互能力。 阅读详情

相关推荐

C++ 优化 `iostream` 性能:同步与缓冲区的底层控制

但这座桥,默认情况下,有点“保守”,为了保证各种兼容性,它做了一些“多余”的事情,导致速度上不去。缓冲区就像一个“蓄水池”,程序先把要输出的数据放到缓冲区里,等缓冲区满了,或者程序显式地刷新缓冲区,才会把数据一次性地输出到屏幕或者文件。想象一下,你辛辛苦苦写了个程序,功能很强大,算法也很牛逼,结果用户用起来,每次输入个数据,或者输出个结果,都要等半天。这玩意儿,说白了,就是让你的程序在输入输出的时候跑得更快一点,别老是慢吞吞的,看着就着急。记住,好的代码,不仅仅是跑得快的代码,更是易于理解和修改的代码。

weixin_41455464的博客 890

C++的cin/cout输入输出流概念及其与缓冲区关系

转自:https://blog.youkuaiyun.com/selina8921/article/details/79067941 其他链接:https://blog.youkuaiyun.com/selina8921/article/details/79067941 https://www.cnblogs.com/gujiayue/p/5536661.html(类比了送快递与cin缓冲) https://bl...

qq_41230365的博客 1186

Linux基础——“C语言高级编程” C语言中的细节你真的知道吗?

文章目录GCC简介 GCC简介 gcc 所支持后缀名解释 .c c原始程序 .C / .cc /.cxx C++原始程

weixin_44278698的博客 2511

cout问题

cout cout 一般的书上说,cout会有缓冲效果,所以当数据比较少的时候会放在缓冲区,但是实践发现,上面二者效果差距不大, 所以cout只要满足一定条件的话也会flush,不一定非要添加转行符来刷新,比如再cout析构时,或者遇到其他输入输出 对象时,所以无需在这种情况再细究。

feng__shuai的博客 491

深入解析BlueZ5与D-Bus:Linux蓝牙开发实战指南

本文深入解析BlueZ5与D-Bus在Linux蓝牙开发中的核心应用,提供从环境搭建到实战开发的完整指南。通过详细代码示例和调试技巧,帮助开发者掌握蓝牙协议栈与D-Bus接口的交互方法,实现高效蓝牙设备管理与GATT服务开发。

weixin_28292761的博客 450

别再只接个放大器了!压电传感器测量电路(电压/电荷放大器)的5个实战配置要点

本文深入解析压电传感器测量电路中的5个关键实战配置要点,包括电缆长度选择、输入阻抗匹配、过载保护设计、低频噪声抑制及放大器选型策略。特别针对电压放大器和电荷放大器的应用场景差异提供工程实践建议,帮助工程师有效解决信号失真、噪声干扰等常见问题,提升测量精度和系统可靠性。

weixin_26869081的博客 302

cout和printf的缓冲机制

2019独角兽企业重金招聘Python工程师标准>>> ...

weixin_34355559的博客 457

VMware共享磁盘配置实战:从零搭建多机共享存储环境

本文详细介绍了在VMware环境中从零开始配置共享磁盘的完整实战流程。通过创建共享磁盘、挂载至多台虚拟机并修改.vmx配置文件等关键步骤,帮助用户搭建可用于数据库集群(如Oracle RAC)测试的多机共享存储环境,并提供了核心参数设置与常见问题排查指南。

weixin_29284201的博客 492

C++学习记录 三:cin / cout(iostream)缓冲buffer的刷新机制

cin和cout

菜狗的玄学修炼室 1994

C#实战:基于ONNX与SCRFD/ArcFace的高效人脸识别系统开发

本文详细介绍了如何在C#环境中,利用ONNX Runtime高效部署SCRFD人脸检测与ArcFace人脸识别模型,构建一个完整的、高性能的人脸识别系统。内容涵盖环境搭建、模型推理、人脸对齐、特征提取等核心模块,并提供了从Demo到生产系统的优化思路与实战代码,为.NET开发者提供了一套开箱即用的解决方案。

weixin_29061821的博客 488

不用API Key也能玩转Obsidian AI:本地大模型离线配置全攻略

本文详细介绍了如何在无需API Key的情况下,通过本地部署大型语言模型(LLM)为Obsidian注入AI能力。文章以Ollama为例,提供了从环境准备、模型选择到与Obsidian插件(如Text Generator)集成的完整配置攻略,旨在帮助用户打造一个安全、离线可用的智能笔记工作流,实现数据隐私与AI助力的完美结合。

weixin_29062963的博客 817

【C++】std::cout与std::cin缓冲区

由于iostream中的cin和cout设有缓冲区(iostream的每个输出流都管理一个缓冲区,用来保存程序读写的数据),当用户要对外部设备写入或读出数据时,会默认将需输出到流对象的内容先放入缓冲区,并不会立即输出,当缓冲区收到刷新信号时,先将数据写入或读出,然后再刷新缓冲区,即清空缓冲区,进行下一轮的读写操作。默认情况下,对cerr是设置unitbuf的,因此写到cerr的内容都是立即刷新的。1.缓冲区已满,当继续向缓冲区写入数据时,写入/读出缓冲区数据,然后刷新缓冲区,再写入下一个数据。

码农努力学习 480

【线粒体基因组数据提交实战】从注释校验到GenBank批量入库的避坑指南

本文详细介绍了线粒体基因组数据从注释校验到GenBank批量上传的全流程避坑指南。重点解析了GB2sequin工具的正确使用方法、TBL注释文件的精修技巧,以及BankIt平台提交的隐藏要点,帮助科研人员高效完成NCBI数据提交,特别适合需要批量上传线粒体基因组数据的研究者。

weixin_28726671的博客 442

Cin、Cout 加快效率方法

std::ios::sync_with_stdio(false); 在main 函数中加上这么一句话。 可以打消iostream的输入输出缓存,可以节省许多时间,使效率与scanf与printf相差无几。 因为 cin,cout之所以效率低,是因为先把要输出的东西存入缓冲区,再输出,导致效率降低。 转载于:https://www.cnblogs.com/wushuaiyi/...

weixin_30872499的博客 221

手把手打通全流程:在华为昇腾310/Atlas 200DK上实现深度学习模型从移植到部署

通过以上步骤,你已成功在华为昇腾310 Atlas 200DK上完成深度学习模型的移植与推理。这一流程可复用到目标检测、语义分割等其他任务,快去尝试将自己的AI模型部署到昇腾设备上,打造属于你的边缘智能应用吧!上部署深度学习模型,这篇教程将带你走完从模型转换到推理运行的完整流程。无需担心技术壁垒,我们以通俗易懂的方式拆解每一步,让你轻松在昇腾嵌入式设备上实现AI应用。是专为边缘AI设计的高性能处理器,Atlas 200DK是其开发板形态,能高效运行图像分类、目标检测等深度学习任务。

FJN110的博客 183

蓝牙模块HM-10手册

蓝牙模块HM-10手册,该手册对蓝牙模块HM-10进行了详细的介绍和使用方法以及一些AT指令。

【STL】iostream 编程:缓冲区的作用

文章摘要:本文通过C++示例揭示了输出缓冲区的特性——程序运行时内容可能暂存缓冲区而非立即显示。演示了使用flush强制刷新缓冲区确保实时输出,对比了endl的功能差异(附加换行),并指出cin/cerr等对象通过tie机制自动刷新cout缓冲区的特性。核心说明了缓冲机制通过减少系统调用来提升性能,强调正确控制缓冲区对交互式程序的重要性。

呆瓜的博客 235

C# WinForm 基于DirectShow.dll编写的程序,可边预览边保存视频,音频和图片

基于微软的DirectShow.dll的二次开发1.自动识别连接的摄像头跟麦克风且可以对其进行选择(默认选中第一个)2.可录制wmv和avi两种格式的视频并且都带有音频,avi可以录制的分辨率和帧数进行选择,wmv默认进行了淸晰度优化如不喜欢可去除代码中有相关提示3.可在预览点开之后进行拍照,也可边录制视频边拍照4.添加了视频和音频的压缩功能(酌情使用)这次二次开发发现C#对DirectShow的相关信息太少,这次做完也不敢藏私共享出来,还望大家指正

C++的cin,cout,endl

在学c语言时我们学的是scanf和printf还有"\n",这些就对应了C++中的cin,cout,endl。cin,cout,endl存在于库函数<iostream>中我们要用他就需要引入这个库或者我们可以用using namespace std 来打开标准库用这三个函数但是在实际项目开发尽不建议用这个让我们看代码来对比一下用法这就是printf和scanf和“\n”的用法和cin,cout,endl的不同 endl其实就是换行,差不多相当于“\n”只不过它多了刷新缓冲区。

Visual_progress的博客 642

IEM模型,地表粗糙度模拟

利用微波反演土壤水分时候,利用IEM模型可以实现对随机地表的模拟

OV9734 DATASHEET,完整规格书

OV9734完整规格书,包括电气参数,尺寸规格,寄存器配置表等

理解C++中的cin和cout

嗯嗯

algsup 1192

cin.sync_with_stdio(false)

在cpp中,因cin和cout要将数据存入缓冲区中再输出,效率缓慢。 采用cin.sync_with_stdio(false)能够取消iostream的输入输出缓存,人为取消同步,使其效率逼近scanf与printf。

BachelorSC ' s Notes 570

C++输入输出机制与流详解

首先C++把输入输出看作字节流; 输入时,程序从输入流中抽取字节; 输出时,程序将字节插入到输出流中; 同时,为了加快程序与磁盘的交互速度,设置内存中的一块内存区域作为缓冲区来缓冲程序的输入与输出; 流作为C++中程序与设备之间的桥梁;因此,C++在处理输入或者输出的时候只对流进行处理,而不管流的源头是什么; 总而言之,C++对输入输出的管理本质上就是对相应的流对象和其缓冲区进行...

冯宝宝 1184

cin.tie(0)和ios::sync_with_stdio(false)

c++输入输出

weixin_45746505的博客 3372

关闭输入输出同步以提高C++的IO效率

默认情况下,C++的标准输入输出库(iostream)会与C语言的标准输入输出库(cstdio)进行同步,以确保二者之间的IO操作不会出现问题。但是,同步会带来一定的性能损失。

2301_78841354的博客 2614

cout、cin等的本质

此文转载于https://www.cnblogs.com/honkly/p/3724647.html我个人认为写的很好,很透彻从原理各方面来详细阐述了iostream。 VC中头文件为:#include &lt;iostream.h&gt; 这个在c中没有。是C++引进的。 cout&lt;头文件#include中printf()类似。 只是不需要标明数据类型。 endl就是end of line...

qianyayun19921028的博客 2009

C++的iostream头文件

C++的iostream头文件

little_startoo的博客 1029

cin,cerr,clog,cout

iostream库:包含两个基础类型istream和ostream。标准库定义了4个IO对象: 1. cin,标准输入,istream类型对象。 2. cout,标准输出,ostream类型对象。 3. cerr,标准错误,输出警告和错误信息,ostream类型对象。 4. clog,输出输出程序运行时的一般信息,ostream类型对象。c++里cerr,clog,cout三者的区别

EmmaXiong 1069
上一篇: 【操作系统学习】(二)同步互斥
下一篇: 用Atom和markdown编辑笔记
codedoctor
博客等级 码龄11年 293粉丝 71原创
评论 6
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值