C/C++相关概念和易错知识点(59)(C/C++缓冲区同步刷新、IO流)

C++IO流 在C语言中,如果想将一个整形变量的数据转化为字符串格式,如何去做呢?1.使用itoa()函数2.使用sprintf()函数都需要先给出保存结果的空间,那空间要给多大呢,这就不太好界定,但两个函数在转化时而且转化格式不匹配时,可能还会得到错误的结果甚至程序崩溃。在C++中,可以使用stringstream类对象来避开此问题,在程序中如果想要使用stringstream,必须要包含头文件<sstream>。 阅读详情

目录

1.C/C++缓冲区同步刷新

(1)产生原因

(2)效率问题即解决方法

(3)cin和cout绑定问题

2.IO流

(1)库的继承体系

(2)IO的四个标志

(3)文件IO

①ofstream、ifstream、fstream

②文本IO和二进制IO

(4)字符串IO

(5)错误信息输出


1.C/C++缓冲区同步刷新

(1)产生原因

C++和C共有两个缓冲区,对应由iostream和cstdio管理,它们各自为各自的缓冲区服务。缓冲区的存在是为了提高效率,在系统的学习中我们能够深刻体会这一点。

以cout和printf为例,在同一个程序里分别使用cout和printf写数据,它们会先放到自己的缓冲区中,我们可以主动调用函数刷新缓冲区,也可以通过触发刷新机制刷新(如\n和endl)。但如果cout代码在printf前,而实际上cout刷新缓冲区的时间比printf晚,这就导致程序打印异常。

因此,要避免打印错乱,C++要兼容C语言,保持同步。当任意一方刷新缓冲区前,都需要先刷新别人的缓冲区,这就是C/C++缓冲区同步刷新。

(2)效率问题即解决方法

每次刷新自己的缓冲区前都要先刷新别人的缓冲区,这就相当于每个输入输出刷新时都需要同时访问两个缓冲区,对于高IO需求的程序,这样的效率影响是很大的。

ios_base::sync_with_stdio(false)可以关闭同步刷新,但是这就会导致上述的问题,因此关闭同步刷新后需要我们手动维护代码的IO顺序性了,最好不要C/C++输入输出混用。

(3)cin和cout绑定问题

 cin和cout是标准输入流对象和标准输出流对象,是在引入<iostream>后全局定义的。

细分C++的缓冲区,也分为输入缓冲区和输出缓冲区。cin和cout是绑定的,意思是调用cin就会先刷新输出缓冲区,调用cout就会先刷新输入缓冲区,这和前面我们遇到的效率问题类似。

cin.tie(nullptr)表示调用cin后不会先刷新输出缓冲区了(即和cout取消绑定),cout.tie(nullptr)表示调用cout后不会先刷新输入缓冲区了。

2.IO流

(1)库的继承体系

这一套IO相关的库可以帮助我们实现C++版的输入输出,可以很方便地替代printf、scanf系列函数。

整个继承体系中含有菱形虚拟继承,C++的IO最大的特点就是通过operator<< 和operator>>支持自定义类型。

(2)IO的四个标志

while(cin >> str)可以持续接收输入

重点关注cin >> str的返回值istream&,istream又重载了一个operator bool,底层上是调用了这个函数来进行类型转换的,等效的判断语句为:cin.operator>>(string str).operator bool()

如何结束呢?换句话说operator bool()内部是如何判断的呢?这就涉及到IO的四个标志了

先看看下面的代码



#include <iostream>
using namespace std;

void cin_state()
{
	printf("cin的状态:\n");
	printf("%d\n", cin.good());
	printf("%d\n", cin.fail());
	printf("%d\n", cin.bad());
	printf("%d\n\n", cin.eof());
}

void cout_state()
{
	printf("cout的状态:\n");
	printf("%d\n", cout.good());
	printf("%d\n", cout.fail());
	printf("%d\n", cout.bad());
	printf("%d\n\n", cout.eof());
}

int main()
{
	string str;
	while (cin >> str)
	{
		cout << "cin接收的字符串:" << str << endl;
	}

	cin_state();
	cout_state();

	cin.clear();
	printf("在这里恢复状态\n\n");

	cin_state();

	return 0;
}


使用^Z可以退出循环,其本质就是修改cin的状态标志

cin和cout都分别有自己的状态标志,默认只有goodbit为1(表示程序正常),其余标志都为0。

其他错误标志:failbit表示基本所有的错误、badbit表示遇到了很严重的错误(如IO流本身被破坏了,和运行程序无关)、eofbit表示读到了文件末尾。

上述代码中,^Z表示读取到了键盘文件的末尾,触发了错误,因此对应为1。通过clear函数,我们可以复原cin对应的状态,上图也可以验证。

我们因此能够理解,operator bool是通过判断cin是否遇到了错误failbit、badbit、eofbit来判断错误的(有eof错误一定会触发fail)

只要我们及时clear状态,就可以让^Z无效

这种情况就只有kill掉整个进程才行了。

只要是继承自ios_base的成员(几乎所有IO相关的对象),基本都有这四个状态

理解了operator bool()的底层依赖,我们就能更好地在判断语句内使用IO函数了,也能知道如何跳出循环,原理是什么。

更多时候我们都是显式使用其中的一个标志来判断结束,这样更易读,如cin.eof()

(3)文件IO

<fstream>专用于文件IO

①ofstream、ifstream、fstream

下面是常用的函数写的代码

open函数默认分别为ofstream只写、ifstream只读,当然也可以指定打开方式

可以看到ofstream主要适用于向文件里面写数据,ifstream适用于从文件里面读数据,和ostream、istream的功能类似,只不过cin和cout是针对显示器文件打印或读取的。

我们还能使用fstream类型,既可读又可写,需要指定打开方式

②文本IO和二进制IO

在Linux系统里面,我们就已经详细分析了文本文件和二进制文件的底层区别。简单来说就是文本文件的数据都被看做字符,经过了一层ASCII码的转换成对应数字后再转成二进制的,而二进制文件直接将数据转成的二进制。文本文件和二进制文件的核心区别就是编解码方式不一样。

默认打开的文件都是文本文件,要以二进制方式打开需要设置参数,如下代码所示

注意string进行二进制写入的话要使用c_str(),本质上write还是C风格的函数,要传入的是对应字符串的首地址而不是string的首地址,否则会导致写入的数据不是字符串对应的二进制,是乱码。

(4)字符串IO

<sstream>用于字符串相关IO

下面是常用函数实例

和前面的一样,只不过输出的对象变成了字符串而已,o向字符串写,i从字符串读。

重点关注istringstream的提取功能。它可以从字符串中读数据并写到不同的对象中,空格就是分割线,和C语言功能基本一致。但注意这个提取的格式和顺序一定要匹配,并且不能跳过某一部分。例如上图要读取2025就必须先读取前面的"Hello",不能跳步骤。

istringstream的构造可以用char*也可以用string,istringstream和ostringstream虽然不是string类型,但里面存放的有字符串的内容,结合上述代码很好理解这一点。

和fstream一样,也有集istringstream和ostringstream一体的stringstream

我们可以直接对着这个类型里面写入字符串,也可读出来,使用方法和前面一致。使用这个类型时很常用的一个函数时str(),就是提取字符串string

(5)错误信息输出

cerr、clog可以用于错误的输出,它们都是ostream的对象且和cout用法完全一致。在代码中可以用它来区分普通打印,主要是增加程序可读性。


 

孤读paper——《GhostNet:More Features from Cheap Operations》 《GhostNet:More Features from Cheap Operations》   发现一个点并解决就是一篇CVPR,该文章主要发现了优秀的网络的特点是feature map提取过程中的冗余性,这种冗余性体现在很多成对的feature map间很像,就好像彼此的“ghost”,而这种特征冗余性对于理解图像来说还是必要的,所以文章把feature map分为两种,一种是本质特征,一... 阅读详情

相关推荐

Wine7.22实战:如何在Ubuntu上完美运行通达信和微信(附字体配置技巧)

本文详细介绍了如何在Ubuntu系统上使用Wine7.22版本,完美运行通达信和微信这两款Windows专属软件。通过选择稳定的Wine7.22版本、利用现成的兼容容器,并重点解决了中文字体渲染的核心难题,提供了从环境搭建、字体配置到软件安装调优的一站式实战指南,帮助用户在Linux环境下无缝使用关键金融与通讯工具。

weixin_29280657的博客 549

C++中刷新输出缓冲区

每一个输出流都管理一个缓冲区,用来保存程序读写的数据。因此要将数据真正写到输出设备中,就需要刷新缓冲区。导致缓冲区刷新的原因大体有以下5种。 1、程序正常结束,作为main函数return操作的一部分,缓冲区被刷新。 2、当缓冲区满了的时候,会刷新缓冲区。 3、可以使用操作符endl、flush和ends来显示的刷新缓冲区。这三个都是IO库中的操作符,endl能完成换行和刷新缓冲区的工作。f...

J_H_C的博客 7336

windows10 + wsl2安装docker

一、安装wsl https://docs.microsoft.com/zh-cn/windows/wsl/install-win10 1.1以管理员身份运行powershell 1.2执行如下命令 dism.exe /online /enable-feature /featurename:Microsoft-Windows-Subsystem-Linux /all /norestart 1.3重启电脑 1.4 重启电脑后,如果需要安装wsl2, 则安装官方文档继续后续操作,因我...

happytree001的博客 1568

c++输出缓冲区刷新

在c++中,io操作都是有io对象来实现的,每个io对象又管理一个缓冲区,用于存储程序读写的数据。 只有缓冲区被刷新的时候缓冲区中的内容才会写入真实的文件或输出设备上。 那么,什么情况下会刷新输出缓冲区呢,有如下五种情况: 1.程序正常结束。作为main返回工作的一部分,将清空所有的输出缓冲区。 2.在一些不确定的时候,缓冲区可能已经满了,在这种情况下,缓冲区将会在写下一个值之前...

dengwenmang7886的博客 593

C#实战:如何用Chart控件打造专业级数据可视化报表(附完整代码)

本文详细介绍了如何使用C#的Chart控件创建专业级数据可视化报表,涵盖柱状图、饼图和雷达图等多种图表类型的高级定制与交互增强。通过完整的代码示例,展示了从环境配置到动态数据绑定的全流程,助力开发者提升企业级应用的数据可视化能力。

ipfs8storage的博客 420

物联网 Mixly-智能楼道灯

一、实验目的及要求 熟悉声音及人体红外传感器用法。 二、实验原理与内容 1.使用声音传感器实现声控灯功能。 2.使用人体红外传感器实现人体检测控制灯功能。 三、实验软硬件环境 硬件:Arduino、LED灯、声音传感器、人体红外传感器 软件:Mixly IDE 四、实验过程(实验步骤、记录、数据、分析) 核心代码截图 声控灯: 人体红外检测灯: 3.实验效果图: (1)、声控灯总线连接: (1)、声控灯声音大于一某个值时灯亮,经过2秒后灯灭: (3)、人体红外检测灯连接总线: (4)、人体红外

qq_43430810的博客 1917

C++刷新缓冲区

今天看到有段代码在输出的时候用到了cout << n << std::flush; 从名称来看知道std::flush的作用肯定是刷新缓冲区,但是测试一下他与cout << n; 感觉没有任何区别。于是只能问度娘了。果然颇有收获。cout << n; 是系统每隔一段时间进行检测输出的。但是由于间隔比较短,让人以为和没有flush一样。而且还知道了,cout << n << std::endl

繁小华的专栏 3859

DDR4内存PCB设计实战:8层板Fly-by拓扑信号完整性优化

本文深入探讨了DDR4内存条在8层PCB板上采用Fly-by拓扑时的信号完整性优化实战。文章详细解析了层叠规划、阻抗控制、电源分割、等长布线及串扰抑制等关键设计要点,并强调了仿真验证的重要性,为硬件工程师提供了从理论到实践的完整设计指南与自查清单。

weixin_29296241的博客 340

C++文件操作(3)

文件操作(3) 1.缓冲区 flush刷新缓冲区 endl换行、刷新缓冲区 设置输出流 2.流状态 eofbit标志位 badbit标志位 failbit标志位 流状态清理 3.文件的删除 4.文件操作的常用方法总结

weixin_54929649的博客 2025

java零基础从入门到精通(全)

目录前言1. 入门知识1.1 java体系1.2 JDK/JRE/JVM区别1.3 编译与运行理解1.4 类体函数细节2. 标识符 前言 java优势 健壮性(JVM(C++语言写的一个虚拟的计算机)、GC(垃圾回收机制)) 多线程并发 可移植性/跨平台 1. 入门知识 1.1 java体系 JavaSE:标准版 JavaEE:企业版 JavaME:微型版 1.2 JDK/JRE/JVM区别 JVM是不能独立安装的。 JRE和JDK都是可以独立安装的 层层嵌套,jvm包括jdk,jdk包括jre

码农研究僧的博客 6万+

Python FastAPI 面试题及参考答案

FastAPI 的路由机制是其核心功能之一,用于将不同的 URL 路径映射到相应的处理函数。通过定义路由,可以构建出功能丰富的 API。在 FastAPI 中,使用装饰器来定义路由。在这个示例中,是一个装饰器,它将根路径"/"的 GET 请求映射到read_root函数。当客户端发送一个 GET 请求到根路径时,FastAPI 会调用read_root函数并返回结果。

大模型大数据攻城狮的专栏 2246

02 C++输入输出缓冲区的刷新问题

在C++中,cin, cout, cerr 分别于stdin, stdout, stderr对应的,即iostream流对象分别与cstdio对应。::sync_with_stdio(false)消除同步,cout和printf就不会按照预期输出,cout与stdout不再共享同一块缓冲区。4.每次输出操作执行完毕后,用unitbuf操纵符设置流的内部状态,从而清空缓冲区。5.输入输出流关联,再读入输入流时刷新对应关联的输出流。2.缓存区满了或者可能满了(大小为1024字节)3.操纵符刷新,如endl。

weixin_54150183的博客 464

2023华为od机试C卷【最富裕的小家庭】C语言 实现

在一颗树中,每个节点代表一个家庭成员,节点的数字表示其个人的财富值,一个节点及其直接相连的子节点被定义为个小家庭。现给你一颗树,请计算出最富裕的小家庭的财富和。

MISAYAONE的博客 499

【C++】IO流

💬 hello!各位铁子们大家好哇。今日更新了C++IO流的相关内容在C语言中,如果想要将一个整形变量的数据转化为字符串格式,如何去做?使用itoa()函数使用sprintf()函数但是两个函数在转化时,都得需要先给出保存结果的空间,那空间要给多大呢,就不太好界定, 而且转化格式不匹配时,可能还会得到错误的结果甚至程序崩溃。在C++中,可以使用stringstream类对象来避开此问题。在程序中如果想要使用stringstream,必须要包含头文件。

qinjh_的博客 3705

数学建模模型总结

这是本人在两年内准备参加数学建模竞赛搜集到的模型资料,已经经过了本人的筛选和整理,希望能够对准备参加数学建模竞赛的学弟学妹们提供一些帮助!

计算机控制技术及应用

《计算机控制技术及应用》通过总结作者的科研成果和吸收国内外的先进理论、方法和技术,以计算机控制系统的网络化、开放化、智能化和集成化发展趋势为主线索,主要介绍计算机控制系统的基本概念和计算机控制系统的典型形式,计算机控制系统的数学描述与基本分析方法,以及数字PID控制器、最少拍控制系统、达林算法、状态变量设计法等设计方法及其各种改进算法。重点突出计算机控制系统输入输出通道接口的设计方法和典型控制系统的设计案例与实现方法等。

【C++】IO库 && IO流

【C++】 IO库 && IO流,一文带你搞懂C++的 IO流

tan_run的博客 1999

IEM模型,地表粗糙度模拟

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

C++ IO流

C语言中用sprintf可以整型转字符串C++中可以用ostringstream,自定义类型转字符串ostringstream是ostream的派生类这里的oss<<d,去调用的是ostream&operator<<,本质上都会以字符串的形式进去out,然后再用str函数取出这个字符串,用string接收。

ljw的博客 1711

【C++】C++的IO流

本篇博客主要介绍的是C++的IO流。的那套东西是面向过程的,C++这套东西是面向过程的。我们可以使用一个类来进行文件的读写,其中最重要的就是把C++对于文本文件读写的方法学一学,用着很方便。其他的作为了解知识学一学。

fight_p的博客 1592

【C++标准IO库】输出缓冲区的管理

C++ 标准 IO 库中的输出缓冲区管理是一个重要的知识点,合理地管理输出缓冲区可以提高程序的性能和效率,保证数据的完整性和及时性。在实际编程中,应该根据具体的需求和场景,选择合适的缓冲区管理方式,避免不必要的刷新操作,处理好异常情况,并注意不同操作系统和编译器的差异。通过掌握输出缓冲区的管理技巧,可以编写出更加健壮、高效的 C++ 程序。

byte轻骑兵的技术小窝 8480

C++的IO流

水从水龙头流出,通过水管流向水槽。在这个过程中,水龙头是水的源头,水槽是水的目的地,水管则是水流动的通道。类似地,在计算机科学中,流可以看作是数据从一个源头(如键盘、文件、网络)流向一个目的地(如屏幕、文件、网络)的通道。​连续性:数据像水流一样连续不断地传输。​方向性:数据有明确的流动方向,从源头流向目的地。​缓冲:流通常会使用缓冲区来临时存储数据,以提高传输效率。在计算机中,流是一种抽象的数据通道,用于处理输入和输出操作。流可以处理各种类型的数据,包括字符、字节、文件等。

azaz_plus的博客 1232

【C++入门到精通】C++的IO流(输入输出流) [ C++入门 ]

本文主要介绍了 C 和 C++ 中的输入输出相关内容。首先介绍了 C 语言中的基本输入输出函数,如 scanf 和 printf 等。然后详细讲解了流的概念和 C++ 中的 IO 流。其中包括标准 IO 流,如 istream、ostream 和 iostream,以及常用的 cin 和 cout 对象,并介绍了文件 IO 流,包括 ifstream、ofstream 和 fstream。最后,本文对 stringstream 进行了简单介绍,包括它的定义、使用方法和作用。整篇文章内容详实,适合初学者阅读。

Yawesh的博客 3139

【与C++的邂逅】--- C++的IO流

类对应操作场景ifstream只读ofstream只写fstream可读可写注:使用文件流对象需要包含对应的头文件<fstream>在C语言中,如果想要将一个整形变量的数据转化为字符串格式,主要有两种方式:1. 使用itoa()函数2. 使用sprintf()函数int main()return 0;注意 : 这两个函数在转化时,都得需要先给出保存结果的空间,空间大小不好界定,而且转化格式不匹配时,可能还会得到错误的结果甚至程序崩溃。

2301_79448270的博客 2512

C++第五十一弹---IO流实战:高效文件读写与格式化输出

C语言的输入与输出,流是什么,C++标准IO流,C++文件IO流,以写方式打开文件,以读方式打开文件,stringstream的简单介绍~~~

小林熬夜学习编程的博客 1714

c++ io 流相关内容

io 相关,fstream 等等相关额内容。

cat_fish_rain的博客 1006

Cpp::IO流(37)

芜湖,要结束喽!其实,“流” 的概念我们之前就有过了解,现在我们再来回顾一下“流” 即是流动的意思,是物质从一处向另一处流动的过程,是对一种有序连续且具有方向性的数据( 其单位可以是bit,byte,packet )的抽象描述而 C++流 是指信息从外部输入设备(如键盘)向计算机内部(如内存)输入和从内存向外部输出设备(显示器)输出的过程。这种输入输出的过程被形象的比喻为 “流”有序连续、具有方向性为了实现这种流动,C++定义了 I/O标准类库 ,这些每个类都称为流 / 流类,用以完成某方面的功能。

tan180°的博客 1109
上一篇: Linux相关概念和易错知识点(31)(生产者-消费者模型、认识信号量、线程安全)
下一篇: Linux相关概念和易错知识点(32)(互斥锁和条件变量的封装、日志和线程池的实现、策略模式)
-SGlow-
博客等级 码龄3年 1513粉丝 118原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值