C++学习记录——삼십이 C++IO流

文章目录

  • 1、C++标准IO流
  • 2、C++文件IO流
    • 1、二进制读写
    • 2、文本读写
  • 3、stringstream


1、C++标准IO流

C语言的printf和scanf无法很好的输入输出自定义类型,且还需要程序员自己确定类型,所以C++就引入了输入流和输出流,是设备和内存之间的沟通。

在这里插入图片描述

其实iostream是通过菱形继承实现的。cout,cerr,clog其实做得有时候没有区分

int main()
{cout << "1111" << endl;cerr << "2222" << endl;return 0;
}

也都能打印出来。fstream和sstream是针对文件和字符串的,对应的就是fprintf/fscanf,fwrite/fread,sprintf/sscanf。C++IO流的特点就是面向对象以及能更好地支持自定义类对象的IO。

istream和ostream是防止拷贝的。

C++IO流的缓冲区和C语言的缓冲区会进行同步,比如用cout和printf混合着输出,也能输出。默认开着同步,也可以关闭同步增强效率。和这个接口有关

在这里插入图片描述

实现了迭代器的容器,通常就不需要重载IO流。

	string str;while (cin >> str){cout << str << endl;}

这样的写法,就可以持续写入字符串,想要停止,就用ctrl + z + 换行来停止,这样是将流对象提取到结束,如果是ctrl + c就是信号强杀进程。我们要知道此时cin >> str是在做什么,>>右边的数据会被获取,给到cin,如果有多个,那就获取多个,最终都流向cin,然后返回一个istream类型的对象,这个对象会被转为bool类型来进行判断,但是一些自定义类型不可以转,像string,而istream可以转是因为类里重载了一个bool()函数,支持自定义类型转内置类型。

在之前的博客中,写到过单参数构造的类支持隐式类型转换

class A
{
public:A(int a):_a(a){}
private:int _a;
};int main()
{A aa1 = 1;return 0;
}

这里的内部实现其实是构造一个临时对象,然后用这个对象来拷贝构造aa1,如果是A&就不行了。这是内置类型转自定义类型,但是自定义转内置不可:int x = aa1。解决办法就是重载一个类型()函数。

	operator int(){return _a;}

如果该函数前面加上explicit就不行了,不过在下面写int x = (int)aa1,强制转换一下也行。

istream里的operator bool(),如果被设置成错误的信息,就返回false,否则返回true,错误的信息例如ctrl + Z + 换行。

2、C++文件IO流

1、二进制读写

#include <fstream>
using namespace std; int main()
{ofstream ofs("F://test.txt");ofs << "hello world";return 0;
}

默认是覆盖写,第二个模板参数默认是ios_base::openmode mode = ios_base::out,ios_base是ofstream和ifstream的父类,如果想要用其它写入模式

在这里插入图片描述

是用 | 来隔开的。

int main()
{ofstream ofs("F://test.txt", ofstream::out | ofstream::app);ofs << "hello world";return 0;
}

看一个读写都有的代码

struct ServerInfo
{char _address[32];int _port;Date _date;
};struct ConfigManager
{
public:ConfigManager(const char* filename):_filename(filename){}void WriteBin(const ServerInfo& info){ofstream ofs(_filename, ofstream::out | ofstream::binary);ofs.write((const char*)&info, sizeof(info));}void ReadBin(ServerInfo& info){ifstream ifs(_filename, ofstream::in | ofstream:::binary);ifs.read((char*)&info, sizeof(info));}private:string _filename; // 配置文件
};int main()
{ServerInfo winfo = { "192.0.0.1", 80, {2023, 9, 4} };string str;cin >> str;if (str == "二进制写"){ConfigManager cm("F://test.txt");cm.WriteBin(winfo);}else if (str == "二进制读"){ServerInfo rinfo;ConfigManager cm("F://test.txt");cm.ReadBin(rinfo);cout << rinfo._address << endl;cout << rinfo._port << endl;cout << rinfo._date << endl;}return 0;
}

二进制读写对象中不能用string,能读进去,但是会崩,而且如果输入的字符串比较长那基本上就是崩掉。

二进制写时,写到文件的是string对象及里面指向空间的指针,程序结束,string自动析构,指针指向的空间销毁了,所以就没法读取,读到的就是野指针。

二进制读写的优点就是简单易操作,缺点就是没法看到实体。

2、文本读写

C语言文本读写的本质是内存中任何类型都转成字符串来交互,C++封装运算符重载后就变得更高效了。

	void WriteText(const ServerInfo& info){ofstream ofs(_filename);ofs << info._address << " " << info._port << " " << info._date;}

日期类中实现了对流插入流提取的重载,不仅ostream能使用,ofstream和osstream都可以用,因为使用了继承体系,ostream是它们的父类。istream也是如此。

	void WriteText(const ServerInfo& info){ofstream ofs(_filename);ofs << info._address << endl;ofs << info._port << endl;ofs << info._date << endl;}void ReadText(ServerInfo& info){ifstream ifs(_filename);ifs >> info._address;ifs >> info._port;ifs >> info._date;}else if (str == "文本写"){ConfigManager cm("F://test.txt");cm.WriteText(winfo);}else if (str == "文本读"){ServerInfo rinfo;ConfigManager cm("F://test.txt");cm.ReadText(rinfo);cout << rinfo._address << endl;cout << rinfo._port << endl;cout << rinfo._date << endl;}

3、stringstream

对应C语言的sprintf和sscanf。

在这里插入图片描述

就像最上面那个图中显示,ios_base是一个基类,ios是它的派生类,istream和ostream是ios的派生类,iostream是istream和ostream的组合,然后istream,ostream,iostream各有分支,stingstream继承于iostream,istringstream继承于istream,ostringstream继承于ostream。

头文件是sstream,不是stringstream。

int main()
{ostringstream oss;oss << 100 << " ";oss << 11.22 << " ";oss << "hello  wolrd" << endl;string str = oss.str();cout << str << endl;return 0;
}

可以把流插入的内容转换成一个字符串,也可以提取出来。

int main()
{ostringstream oss;oss << 100 << " ";oss << 11.22 << " ";oss << "hello  wolrd" << endl;string str = oss.str();cout << str << endl;istringstream iss(str);int i;double d;string s;iss >> i >> d >> s;cout << i << endl;cout << d << endl;cout << s << endl;return 0;
}

iss后面的顺序也得和oss拿到的顺序一样,要不然会使得某些变量内容不对,但也能打印出来。oss和iss也可以换成stringstream的类型。

这个功能主要用于序列化和反序列化

struct ChatInfo
{string _name;int _id;string _msg;
};int main()
{ChatInfo winfo = { "张三", 123456, "你好" };return 0;
}

像这样,我们就可以用ostringstream把内容放到一个字符串,然后发送给需要这些信息的人,别人收到后,就可以用istringstream来提取。不过插入的时候每个后面都加上换行或者空格,因为提取时默认以换行或者空格来分割。

复杂的实际情况还有其它方法。

C++IO流

结束。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/70263.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Matlab信号处理2:方波信号的合成与分解

周期信号可展开为傅里叶级数&#xff0c;因此方波信号可用若干谐波去拟合。以下是Matlab的实现&#xff1a; %% 方波信号的分解% 1.生成方波信号 % 方波信号周期、基波频率 T0 2; w0 (2 * pi) / T0; % 方波信号值为1的区间 T1 0.5; % 绘图周期&#xff1a;(2*n1)个周期 n …

java利用aop来记录接口的请求耗时、请求参数、请求url等详细信息

最近在项目里面需要对一些controller接口进行记录。记录的信息包括&#xff0c;接口的耗时、请求参数、请求url、是否成功、请求的ip地址。 最后利用aop切面编程。 Order(1) Aspect Component Slf4j public class BehaviorAop {AutowiredBehaviorService behaviorService;/**…

C语言结构体的初始化方式

逐个初始化字段&#xff1a;这是最直接的方式&#xff0c;你可以逐个为结构体的每个字段进行初始化。 struct Student { char name[50]; int age; float marks; }; struct Student student1 {"Alice", 20, 89.5}; 2.使用结构体字面值初始化&#xff1a;这种方…

Elasticsearch 分布式搜索——聚合

1.聚合的种类 聚合常见的有三类&#xff1a; **桶&#xff08;Bucket&#xff09;**聚合&#xff1a;用来对文档做分组 TermAggregation&#xff1a;按照文档字段值分组&#xff0c;例如按照品牌值分组、按照国家分组Date Histogram&#xff1a;按照日期阶梯分组&#xff0c;例…

用户忠诚度:小程序积分商城的用户保持方法

随着移动互联网的蓬勃发展&#xff0c;小程序积分商城已经成为了许多企业私域营销的热门选择。这个商城不仅可以吸引用户参与&#xff0c;还可以提高用户的忠诚度&#xff0c;进一步加深用户与品牌的互动关系。然而&#xff0c;要实现用户的忠诚度&#xff0c;需要一系列的策略…

C++的内存管理是怎样的?

目录 C的内存管理代码段数据段BSS段堆区映射区栈区 C的内存管理 在C中&#xff0c;虚拟内存分为代码段、数据段、BSS段、堆区、文件映射区、栈区六部分&#xff1a; 代码段 包括只读存储区和文本区&#xff0c;其中只读存储区存储字符串常量,文本区存储程序的机器代码。 数据…

生信豆芽菜-机器学习筛选特征基因

网址&#xff1a;http://www.sxdyc.com/mlscreenfeature 一、使用方法 1、准备数据 第一个文件&#xff1a;特征表达数据 第二个文件&#xff1a;分组信息&#xff0c;第一列为样本名&#xff0c;第二列为患者分组 第三个文件&#xff1a;分析基因名 2、选择机器学习的方…

【C语言】入门——结构体

目录 结构体 为什么有结构体&#xff1f; 1.结构体的声明 1.2结构体变量的访问和初始化 2.结构体成员的访问 结构体 struct 结构体类型 {//相关属性; }结构体变量; 结构体和数组不同&#xff0c;同一类型的数据的集合是数组&#xff1b; 结构体是多种类型的数据的集合&…

使用GPT-4生成训练数据微调GPT-3.5 RAG管道

OpenAI在2023年8月22日宣布&#xff0c;现在可以对GPT-3.5 Turbo进行微调了。也就是说&#xff0c;我们可以自定义自己的模型了。然后LlamaIndex就发布了0.8.7版本&#xff0c;集成了微调OpenAI gpt-3.5 turbo的功能 也就是说&#xff0c;我们现在可以使用GPT-4生成训练数据&a…

被百度判定为低质量网站了!如何整改?

我是卢松松&#xff0c;点点上面的头像&#xff0c;欢迎关注我哦&#xff01; 先说结论&#xff1a;接受现实&#xff0c;不要幻想百度恢复了! 百度自9月初大批量删除百度资源平台权限以来&#xff0c;几乎90%(未经证实**&#xff0c;但数量确实不小)的网站都被取消了权限&am…

vue3中的reactive赋值问题

问题 当通过方法对reactive变量修改的时候&#xff0c;发现页面上的值没有及时更新&#xff1f; 解决方法 具体原因: 上面这样赋值检测不到&#xff0c;因为响应式的是它的属性&#xff0c;而不是它自身. 方法1: 单个赋值 如下&#xff1a; let obj reactive({name: zha…

MySql学习笔记07——存储引擎介绍

存储引擎 Mysql中特有的术语&#xff0c;Oracle中没有。 存储引擎就是一个表存储/组织数据的方式。不同的存储引擎&#xff0c;表存储数据的方式不同。 指定存储引擎 在建表的时候可以在最后小括号的")"的右边使用&#xff1a; ENGINE来指定存储引擎。 CHARSET来…

YOLO目标检测——火焰检测数据集+已标注xml和txt格式标签下载分享

实际项目应用&#xff1a;火灾预警系统、智能监控系统、工业安全管理、森林火灾监测以及城市规划和消防设计等应用场景中具有广泛的应用潜力&#xff0c;可以提高火灾检测的准确性和效率&#xff0c;保障人员和财产的安全。数据集说明&#xff1a;YOLO火焰目标检测数据集&#…

GuLi商城-前端基础Vue-整合ElementUI快速开发

npm安装 启动项目&#xff1a;npm run dev http://localhost:8082/#/hello

02-Tomcat打破双亲委派机制

Tomcat 如果使用默认的双亲委派类加载机制行不行&#xff1f; 我们思考一下&#xff1a;Tomcat是个web容器&#xff0c; 那么它要解决什么问题&#xff1a; 一个web容器可能需要部署两个应用程序&#xff0c;不同的应用程序可能会依赖同一个第三方类库的不同版本&#xff0c;…

记:一次关于paddlenlp、python、版本之间的兼容性问题

兼容版本 Python 3.10.8 absl-py1.4.0 accelerate0.19.0 addict2.4.0 aiofiles23.1.0 aiohttp3.8.3 aiosignal1.3.1 alembic1.10.4 aliyun-python-sdk-core2.13.36 aliyun-python-sdk-kms2.16.0 altair4.2.2 altgraph0.17.3 aniso86019.0.1 antlr4-python3-runtime4.9.3 anyi…

问道管理:华为产业链股再度拉升,捷荣技术6连板,华力创通3日大涨近70%

华为产业链股6日盘中再度拉升&#xff0c;到发稿&#xff0c;捷荣技能涨停斩获6连板&#xff0c;华映科技亦涨停收成3连板&#xff0c;华力创通大涨超19%&#xff0c;蓝箭电子涨约11%&#xff0c;力源信息涨超4%。 捷荣技能盘中再度涨停&#xff0c;近7日已累计大涨超90%。公司…

Pycharm通用设置个性化设置

Pycharm通用设置&个性化设置 通用设置取消打开Pycharm自动进入项目开启【Ctrl鼠标滑轮】放大缩小字体 个性化设置设置彩虹括号 通用设置 取消打开Pycharm自动进入项目 选择选择菜单【File】>【Settings】进入设置页面选择【Appearance & Behavior】>【System S…

Git使用经验总结3-删除远端提交记录

文章目录 1. 问题2. 解决方案3. 参考 1. 问题 如果将有问题的代码提交到代码仓库甚至已经push到远端&#xff0c;这个时候就得想办法把提交撤销。一种方案是使用git revert&#xff0c;不过会造成历史记录留存的问题&#xff0c;git revert实际上是将某个版本又重新提交了一遍…

c++中的对齐问题

c中的对齐问题 需要对齐的原因 尽管内存是以字节为单位&#xff0c;但是大部分处理器并不是按字节块来存取内存的.它一般会以双字节,四字节,8字节,16字节甚至32字节为单位来存取内存&#xff0c;我们将上述这些存取单位称为内存存取粒度. 现在考虑4字节存取粒度的处理器取in…