C++知识点 -- C++的IO流

news2024/9/22 14:31:26

C++知识点 – C++的IO流

文章目录

  • C++知识点 -- C++的IO流
  • 一、C++标准IO流
    • 1.多个输入数据
    • 2.多行数据读入
  • 二、C++文件IO流
    • 1.ifstream读文件
    • 2.文件读写类
  • 三、stringstream


一、C++标准IO流

在这里插入图片描述
C++系统实现了一个庞大的类库,其中以ios为基类,其他类都是直接或间接派生自ios类;

C++标准IO流提供了4个全局流对象,cin、cout、cerr、clog,其中最常用的就是cin和cout;
ostream/istream 更好支持自定义类型对象的流插入和流提取;
自定义类型,可以自己重载,控制流提取和流插入的方式;

1.多个输入数据

void test()
{
	int year, month, day;
	cin >> year >> month >> day;
	scanf("%d%d%d", &year, &month, &day);
	//scanf("%d %d %d", &year, &month, &day);//中间不需要加空格
}

cin和scanf输入多个值都是默认使用空格或者换行符分割的,中间不用加空格;

如果是20230112这种格式的输入:

void test()
{
	//如果是20230112这种格式
	int year, month, day;
	scanf("%4d%2d%2d", &year, &month, &day);//scanf可以用这种方式

	//c++就需要使用string的字符分割
	string str;
	cin >> str;
	year = stoi(str.substr(0, 4));
	month = stoi(str.substr(4, 2));
	day = stoi(str.substr(6, 2));
}

2.多行数据读入

c语言可以使用scanf() != EOF来读取;
c++的读取方式如下:

void test()
{
	int year, month, day;

	string str;
	while (cin >> str)
	{
		year = stoi(str.substr(0, 4));
		month = stoi(str.substr(4, 2));
		day = stoi(str.substr(6, 2));
	}
}

结束程序可以用ctrl + Z + 换行 或者 ctrl + c

原因是cin读取数据后还会返回bool值,cin返回布尔值是通过重载operator bool实现的;
当读到文件末尾或者错误时,会返回false;

在这里插入图片描述
在这里插入图片描述
这里涉及到隐式类型转换

class A
{
public:
	A(int a)
		: _a(a)
	{}

	operator int()//operator int支持了自定义类型转换成内置类型
	{
		return _a;
	}
private:
	int _a;
};

void test()
{
	//内置类型 转换为 自定义类型
	A a1 = 1; // 隐式类型转换, 先用1构造A临时对象,再拷贝构造,优化后直接调用构造

	//自定义类型 转换为 内置类型
	int i = a1; // 原本编译器是不支持的,但是A中重载了operator int 后,就支持自定义类型转换成内置类型
}

二、C++文件IO流

C++文件IO流中包含三个对象:
ifstream:只输入用
ofstream:只输出用
fstream:既能输入又能输出

1.ifstream读文件

class Date
{
	friend ostream& operator << (ostream& out, const Date& d);
	friend istream& operator >> (istream& in, Date& d);
public:
	Date(int year = 1, int month = 1, int day = 1)
		:_year(year)
		, _month(month)
		, _day(day)
	{}

	operator bool()
	{
		// 这里是随意写的,假设输入_year为0,则结束
		if (_year == 0)
			return false;
		else
			return true;
	}
private:
	int _year;
	int _month;
	int _day;
};

istream& operator >> (istream& in, Date& d)
{
	in >> d._year >> d._month >> d._day;
	return in;
}

ostream& operator << (ostream& out, const Date& d)
{
	out << d._year << " " << d._month << " " << d._day;
	return out;
}

void test()
{
	ifstream ifs("text.txt");//可以直接用文件路径构造ifstream对象,就直接打开文件了

	//ifstream ifs();
	//ifs.open("text.txt");//也可以构造空对象,再调用fopen打开文件

	int i;
	string str1, str2;
	Date d1;

	ifs >> i >> str1 >> d1 >> str2;
}

构造ifstream对象之后就可以打开文件进行读取了,ifstream对象支持流提取,从文件中直接提取对象;
使用ifstream的流提取,是继承于istream的;
这里c++的流提取支持直接提取到自定义类型(前提是自定义类型重载了流提取);

2.文件读写类

二进制读写文件

struct SeverInfo
{
	char _address[32];
	int _port;
};

class ConfigManager
{
public:
	ConfigManager(string filename = "sever.config")
		: _filename(filename)
	{}

	//二进制写
	void WriteBin(const SeverInfo* info)
	{
		ofstream ofs(_filename, ios_base::out | ios_base::binary);//二进制写
		ofs.write((char*)info, sizeof(SeverInfo));
	}

	//二进制读
	void ReadBin(SeverInfo& info)
	{
		ifstream ifs(_filename, ios_base::in | ios_base::binary); //二进制读
		ifs.read((char*)&info, sizeof(SeverInfo));
	}

private:
	string _filename;
};

void test()
{
	//二进制写文件
	SeverInfo winfo = { "127.0.1", 888 };
	ConfigManager cm;
	cm.WriteBin(&winfo);

	//二进制读文件
	SeverInfo rinfo;
	cm.ReadBin(rinfo);
	cout << rinfo._address << endl;
	cout << rinfo._port << endl;
}

二进制读写时,ifstream和ofstream对象的第二个参数应该使用in/out和binary的组合,多个状态组合中间用 | 分割;
在这里插入图片描述
如果将SeverInfo中的address从char* 换成string,就会出错,关系到c++的string的设计问题;
在这里插入图片描述
在这里插入图片描述
长字符串是存在指针处的,写完之后进程结束,指针释放,读的时候下一个进程给的ptr不是一个地址,就会出现读取错误;

所以说二进制不适合深拷贝的类型;

文本读写文件

struct SeverInfo
{
	//char _address[32];
	string _address;
	int _port;
};

class ConfigManager
{
public:
	ConfigManager(string filename = "sever.config")
		: _filename(filename)
	{}

	//文本写
	void WriteText(const SeverInfo* info)
	{
		ofstream ofs(_filename, ios_base::out);//二进制写
		ofs.write(info->_address.c_str(), info->_address.size());
		ofs.put('\n');
		const string str = to_string(info->_port);
		ofs.write(str.c_str(), str.size());
	}

	//文本读
	void ReadText(SeverInfo& info)
	{
		ifstream ifs(_filename, ios_base::in); //二进制读
		char buff[128];
		ifs.getline(buff, 128);
		info._address = buff;
		ifs.getline(buff, 128);
		info._port = stoi(buff);
	}

private:
	string _filename;
};

这是使用write和read进行读写,更加方便地方式是使用流插入和流提取进行读写

struct SeverInfo
{
	//char _address[32];
	string _address;
	int _port;
};

class ConfigManager
{
public:
	ConfigManager(string filename = "sever.config")
		: _filename(filename)
	{}

	void WriteText(const SeverInfo& info)
	{
		ofstream ofs(_filename, ios_base::out);
		ofs << info._address << endl;
		ofs << info._port << endl;
	}

	void ReadText(SeverInfo& info)
	{
		ifstream ifs(_filename, ios_base::in | ios_base::binary);
		ifs >> info._address >> info._port;
	}

private:
	string _filename;
};

三、stringstream

字符串流:完成字符串和其他类型之间的转换;

将提取到的信息转换为字符串存储到流中:

void test()
{
	// 序列化
	ChatInfo winfo = { "张三", 135246, { 2022, 4, 10 }, "晚上一起看电影吧" };
	//ostringstream oss;
	stringstream oss; // stringstream既有ostringstream的功能,也有istringstream的功能
	oss << winfo._name << endl;
	oss << winfo._id << endl;
	oss << winfo._date << endl;
	oss << winfo._msg << endl;

	//可以通过oss.str拿到流中的字符串
	string str = oss.str();
	cout << str << endl;
}

将流中的字符串转为其他类型

void test()
{
	// 序列化
	ChatInfo winfo = { "张三", 135246, { 2022, 4, 10 }, "晚上一起看电影吧" };
	//ostringstream oss;
	stringstream oss;
	oss << winfo._name << endl;
	oss << winfo._id << endl;
	oss << winfo._date << endl;
	oss << winfo._msg << endl;

	string str = oss.str();
	cout << str << endl;

	// 网络传输str,另一端接收到了字符串串信息数据

	// 反序列化
	ChatInfo rInfo;
	//istringstream iss(str);
	//使用提取到的str来构造strinfstream对象,拿到字符串
	stringstream iss(str);
	iss >> rInfo._name;
	iss >> rInfo._id;
	iss >> rInfo._date;
	iss >> rInfo._msg;

	cout << "----------------------------------" << endl;
	cout << rInfo._date << endl;
	cout << rInfo._name << "[" << rInfo._id << "]:>" << rInfo._msg << endl;
	cout << "----------------------------------" << endl;
}

在这里插入图片描述
stringstream的优势在于可以对自定义类型进行处理;

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

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

相关文章

springboot 阿里云oss图片上传和异常处理

自己去申请开通阿里云oss。 对象存储 OSS_云存储服务_企业数据管理_存储-阿里云 1.在pom.xml添加依赖 <dependency><groupId>com.aliyun.oss</groupId><artifactId>aliyun-sdk-oss</artifactId><version>3.14.0</version></dep…

港科夜闻|香港科大与香港资管通有限公司签署校企合作备忘录,成立校企合作基金促科研成果落地...

关注并星标 每周阅读港科夜闻 建立新视野 开启新思维 1、香港科大与香港资管通有限公司签署校企合作备忘录&#xff0c;成立校企合作基金促科研成果落地。“港科资管通领航基金”28日在香港成立&#xff0c;将致力于推动高校科研成果转化&#xff0c;助力香港国际创科中心建设。…

Fabric.js 拖拽顶点修改多边形形状

theme: smartblue 我正在参加「掘金启航计划」 本文简介 戴尬猴&#xff0c;我是德育处主任 这次要介绍的一个demo是"拖拽多边形定点修改多边形形状"。 其实 Fabric.js 官网也有这个demo&#xff1a;Fabric.js demos Custom controls, polygon 。但这个demo可能对于…

ASEMI代理ADV7611BSWZ原装ADI车规级ADV7611BSWZ

编辑&#xff1a;ll ASEMI代理ADV7611BSWZ原装ADI车规级ADV7611BSWZ 型号&#xff1a;ADV7611BSWZ 品牌&#xff1a;ADI/亚德诺 封装&#xff1a;LQFP-64 批号&#xff1a;2023 引脚数量&#xff1a;64 工作温度&#xff1a;-40C~85C 安装类型&#xff1a;表面贴装型 …

怎么轻松地搞定Win11系统备份任务?

“我是一个电脑小白&#xff0c;不是很懂电脑的一些操作。我刚买了一台新电脑&#xff0c;它装的是Win11系统&#xff0c;我害怕它出现什么问题&#xff0c;听朋友说可以通过备份的方法保护系统&#xff0c;这是真的吗&#xff1f;有谁知道该怎么进行Win11系统备份吗&#xff1…

OJ练习第101题——柱状图中最大的矩形

柱状图中最大的矩形 力扣链接&#xff1a;84. 柱状图中最大的矩形 题目描述 给定 n 个非负整数&#xff0c;用来表示柱状图中各个柱子的高度。每个柱子彼此相邻&#xff0c;且宽度为 1 。 求在该柱状图中&#xff0c;能够勾勒出来的矩形的最大面积。 示例 思路 我们先嵌…

第2章 Nginx环境搭建

第2章 Nginx环境搭建 2.1 下载 免费开源版的官方网站&#xff1a;http://nginx.org Nginx 有 Windows 版本和 Linux 版本&#xff0c;但更推荐在 Linux 下使用 Nginx&#xff1b; 下载nginx-1.14.2.tar.gz的源代码文件&#xff1a;wget http://nginx.org/download/nginx-1.…

登录功能实现及文件上传下载功能补充

登录功能实现简单介绍&#xff1a; 1&#xff1a;登录时密码输入错误刷新登陆页面并提示登录信息错误&#xff1b; 2&#xff1a;输入正确用户名及密码点击sign in 登录成功。&#xff08;如果勾选remember me 只要服务器未停止&#xff0c;可以直接免登录进入欢迎页面&#x…

《光电容积法在评估高血压中的应用》阅读笔记

目录 一、论文摘要 二、论文十问 Q1&#xff1a;论文试图解决什么问题&#xff1f; Q2&#xff1a;这是否是一个新的问题&#xff1f; Q3&#xff1a;这篇文章要验证一个什么科学假设&#xff1f; Q4&#xff1a;有哪些相关研究&#xff1f;如何归类&#xff1f;谁是这一课…

ubuntu系统配置软件脚本自启动

背景 项目因为某些原因需要服务器自启动来执行脚本, 因此需要在ubuntu服务器上面实现自启动功能. 步骤 ubuntu作为服务器使用时&#xff0c;常常需要在机器重启时能自动启动我们开发的服务。 Ubuntu 18.04不再使用initd管理系统&#xff0c;改用systemd&#xff0c;包括用sys…

Redis:哨兵集群

目录 基于pub/sub 机制的哨兵集群组成基于pub/sub 机制的客户端事件通知由哪个哨兵执行主从切换哨兵实例是不是越多越好&#xff0c;如果同时调大 down-after-milliseconds 值&#xff0c;对减少误判是不是也有好处 部署多个哨兵实例就形成了一个哨兵集群。哨兵集群中的多个实例…

【Redis】Redis面试题

Redis的事务 什么是Redis的事务 Redis的事务是一个单独的隔离操作&#xff0c;事务中的所有命令都会序列化、按顺序地执行。事务在执行的过程中&#xff0c;不会被其他客户端发送来的命令请求所打断&#xff0c;所以Redis事务是在一个队列中&#xff0c;一次性、顺序性、排他…

人工智能基础:从机器学习到深度学习的发展和应用

随着信息技术的快速发展&#xff0c;人工智能技术已经成为当今最热门的技术之一。在人工智能技术中&#xff0c;机器学习和深度学习是最为关键的两个技术分支。本文将从机器学习的基础概念、机器学习的发展史、深度学习的基本概念、深度学习的应用以及深度学习的未来趋势等方面…

Chunjun数据同步工具初体验

chunjun (纯钧) 官方文档纯钧 chunjun 有四种运行方式&#xff1a;local、standalone、yarn session、yarn pre-job 。 运行方式/环境依赖flink环境hadoop环境localstandalone√yarn session√√yarn pre-job√√ 1.下载 官网已经提供了编译好的插件压缩包&#xff0c;可以…

【译】Java 内存泄露的构造和检测

1. 概述 在 Java 应用程序中&#xff0c;内存泄漏会导致严重的性能下降和系统故障。开发人员必须了解内存泄漏的发生原因以及如何识别和解决它们。 在本教程中&#xff0c;我们将提供一个使用失效的监听器问题作为示例来创建 Java 内存泄漏的指南。我们还将讨论各种检测内存泄…

GitHub Copilot 使用介绍

什么是 Github Copilot https://github.com/features/copilot Github Copilot 是一种人工智能辅助开发工具&#xff0c;由 GitHub 和 OpenAI 合作开发&#xff0c;旨在通过机器学习算法为开发人员提供自动化的代码提示和智能建议&#xff0c;从而提高开发效率&#xff0c;该系…

【Vue】 CLI WebStorage

CLI 本地存储 自定义事件 WebStorage(js本地存储)localStoragesessionStorage WebStorage(js本地存储) 存储内容大小一般支持5MB左右(不同浏览器可能还不一样) 浏览器端通过Window.sessionStorage 和Winodw.localStorage 属性来实现本地存储机制相关API xxxStorage.setItem(‘…

TCP协议介绍

文章目录 一、TCP协议二、TCP协议段格式4位首部长度可靠性理解32位序号和32位确认序号16位窗口大小TCP协议中的6个标记位16位紧急指针 三、TCP三次握手和四次挥手TCP的三次握手TCP的四次挥手状态变化 四、超时重传机制五、滑动窗口高速重发机制(快重传) 六、流量控制七、拥塞控…

Java分布式事务(十八)

文章目录 🔥最终一致性分布式事务解决方案_什么是最大努力通知型分布式事务🔥最大努力通知型分布式事务_最大努力通知与可靠消息最终一致性的区别🔥最大努力通知型分布式事务解决方案🔥最大努力通知型分布式事务_案例业务说明🔥最大努力通知型分布式事务实战_实现充值…

Adobe XD 下载和安装教程

文章目录 Adobe XD 简介Adobe XD 下载Creative Cloud 下载与安装Adobe XD 下载 Adobe XD 安装Adobe XD 启动 Adobe XD 简介 Adobe XD是一个协作式易用平台&#xff0c;可帮助团队为网站、移动应用程序、语音界面、游戏等创建设计。 Adobe XD是一站式UX/UI设计平台&#xff0c;…