序列化和反序列化(简单)(c++)

2023-11-15

序列化和反序列化(简单)(c++)

最近看了看序列化相关的,动手试着做了一下。虽然感觉自己很菜,但还是忍不住分享。由此记录成长:
什么事序列化呢:(我的理解):
将数据转换成字节流存进内存:序列化
从指定内存取出字节流,再把字节流转换成数据:反序列化
那我们需要准备申请一块内存空间:

char* m_arr;
m_arr = new char[256];

我们取数据就需要精确的从内存里面找到该数据所在内存空间的下标:利用指针偏移
所以我们需要一个变量记录指针偏移量:

int m_index = 0;

比如下图中,第一个数据存的是一个int类型的数据,大小为4个字节,第二个为bool类型的数据,大小为1个字节。

存数据(因为是char*类型数组,所以赋值需要强转)

//value是外部传进来的int类型数据
*(int*)&m_arr[m_index] = value;
指针偏移
m_index +=sizeof(int);

//value是外部传进来的bool类型数据
*(bool*)&m_arr[m_index] = value;
m_index +=sizeof(bool);

在这里插入图片描述
反序列化就是直接反过来,利用指针偏移,拿到相应的数据,再根据自己所需要的类型进行强转:

存数据(因为是char*类型数组,所以赋值需要强转)

//value是外部传进来的int类型数据存储,调用了引用
value =*(int*)&m_arr[m_index] ;
指针偏移
m_index +=sizeof(int);

//value是外部传进来的bool类型数据存储,调用了引用
value = *(bool*)&m_arr[m_index];
m_index +=sizeof(bool);

按照上面的步骤,粘贴复制得到可以转换的其他类型就可以了:
不过容器需要特殊处理,原理差不多:
比如string类型:

	//得到string大小,value是外部传进来的string类型数据
	int szienum = value.size();
	//将长度存进去,后面反序列化的时候就好拿数据长度了
	oeprMath::operator<<(szienum);
	for (int i = 0; i < szienum; i++)
	{
		//在把数据一个一个存进去
		*(char*)&m_arr[m_index] = value[i];
		m_index += 1;
	}
	

取数据差不多:

	int sizenum = *(int*)&m_arr[m_index];
	m_index += sizeof(int);

	string test = "";
	for (int i = m_index; i < m_index + sizenum; i++)
	{
		char numa =m_arr[i];
		if (numa)
		{
			test+=m_arr[i];
		}
	}
	value = test;
	m_index +=sizenum;
	

最后上我做的demo:c++版的
.h文件

#pragma once
#include <string>
using namespace std;


#define M_STRING 28;
#define M_BOOL 1;
#define M_INT 4;
#define M_SHORT 2;
#define M_LONG 4;

class oeprMath
{
public:
	oeprMath();
	~oeprMath();
	void operator<<(bool& value);
	void operator<<(int& value);
	void operator<<(string& value);
	void operator<<(long& value);
	void operator<<(short& value);
	void operator<<(char& value);

	void operator>>(bool& value);
	void operator>>(int& value);
	void operator>>(string& value);
	void operator>>(long& value);
	void operator>>(short& value);
	void operator>>(char& value);

	char* arr();
	void setarr(char* arr)
	{
		m_index = 0;
	}
private:
	char* m_arr;
	int m_index = 0;
};

	

.cpp文件:

#include "oeprMath.h"

oeprMath::oeprMath()
{
	m_arr = new char[256];
}

oeprMath::~oeprMath()
{
}

void oeprMath::operator<<(bool& value)
{
	*(bool*)&m_arr[m_index] = value;
	m_index += M_BOOL;
}

void oeprMath::operator<<(int& value)
{
	*(int*)&m_arr[m_index] = value;
	m_index += M_INT;
}

void oeprMath::operator<<(string& value)
{
	int szienum = value.size();
	//将长度存进去,后面反序列化的时候就好拿数据长度了
	oeprMath::operator<<(szienum);
	for (int i = 0; i < szienum; i++)
	{
		oeprMath::operator<<(value[i]);
	}
	
}

void oeprMath::operator<<(long& value)
{
	*(long*)&m_arr[m_index] = value;
	m_index += M_LONG;
}

void oeprMath::operator<<(short& value)
{
	*(short*)&m_arr[m_index] = value;
	m_index += M_SHORT;
}

void oeprMath::operator<<(char & value)
{
	*(char*)&m_arr[m_index] = value;
	m_index += 1;
}

void oeprMath::operator>>(bool& value)
{
	value=*(bool*)&m_arr[m_index];
	m_index += M_BOOL;
}

void oeprMath::operator>>(int& value)
{
	 value =*(int*)&m_arr[m_index] ;
	m_index += M_INT;
}

void oeprMath::operator>>(string& value)
{
	int sizenum = *(int*)&m_arr[m_index];
	m_index += M_INT;

	string test = "";
	for (int i = m_index; i < m_index + sizenum; i++)
	{
		char numa =m_arr[i];
		if (numa)
		{
			test+=m_arr[i];
		}
	}
	value = test;
	m_index +=sizenum;
}

void oeprMath::operator>>(long& value)
{
	value=*(long*)&m_arr[m_index];
	m_index += M_LONG;
}

void oeprMath::operator>>(short& value)
{
	value=*(short*)&m_arr[m_index];
	m_index += M_SHORT;
}
void oeprMath::operator>>(char & value)
{
	value = *(char*)&m_arr[m_index];
	m_index += 1;
}
char* oeprMath::arr()
{
	return m_arr;
}	

main函数调用:

// socketSever.cpp : 此文件包含 "main" 函数。程序执行将在此处开始并结束。
//
#pragma comment(lib, "ws2_32.lib")

#include <winsock2.h>
#include <iostream>
#include <string>
#include "oeprMath.h"
using namespace std;

struct cscom
{
	int id;
	long name;
	bool isopen;
	string name1;
};
char *m_arr;
void write(oeprMath &oper,cscom &vo)
{
	oper << vo.id;
	oper << vo.name;
	oper << vo.isopen;
	oper << vo.name1;
}
void read(oeprMath &oper, cscom &vo)
{
	oper >> vo.id;
	oper >> vo.name;
	oper >> vo.isopen;
	oper >> vo.name1;
}


int main()
{
	cout << sizeof(char) << endl;
	cscom testcom;
	testcom.id = 1;
	testcom.name = 233;
	testcom.name1 = "namess";
	testcom.isopen = true;

	oeprMath testmath;
	write(testmath, testcom);
	m_arr =testmath.arr();
	cout << m_arr << endl;
	cscom readarr;
	testmath.setarr(testmath.arr());
	read(testmath, readarr);
	cout << readarr.id << endl << readarr.name << endl << readarr.isopen << endl << readarr.name1 << endl;
}

ps:序列化和反序列化的时候,存和取数据的结构不能乱。
就酱

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

序列化和反序列化(简单)(c++) 的相关文章

随机推荐

  • MQL5:zig-zag 指标

    Zig Zag 指标是用于描述高低点趋势的指标 MQL5 官方实现 MQL5 官方实现十分地烂 辣鸡 很多无用的变量 程序冗长 不一致 效率低下 感觉是多个菜鸟合作写出来的 有一些没有用的变量都没有删掉 不过 先来看看MQL5的官方实现 辅
  • 在ActiveX控件中如何动态调用DLL函数

    刚到公司不久 接到领导的下达的一个任务 就是把对POS机操作功能封装在ActiveX控件中 在IE中调用 这样就能实现在IE上直接对POS机进行操作 而我要封装的这个动态库 厂家只提供了一个单的动态库和一百多字的说明 也就是说明一下动态库中
  • vue笔记-inheritAttrs及$attr表示含义(一)

    一 引用官方解释 inheritAttrs 默认值true 在这种情况下父作用域的不被认作 props 的特性绑定 attribute bindings 将会 回退 且作为普通的 HTML 特性应用在子组件的根元素上 attr 包含了父作用
  • 服务器网站用绝对路径,云服务器上的绝对路径

    云服务器上的绝对路径 内容精选 换一换 已成功登录Java性能分析 待安装分析辅助软件的服务器已开启sshd Java性能分析优先选用非交互shell non interactive shell 中的JAVA HOME环境变量所指定的JRE
  • 关于iptables -m选项以及规则的理解

    关于iptables的详细状态可以查看http os 51cto com art 201108 285209 htm 时常在服务器的防火墙上看到有这些规则 2 106K 8294K ACCEPT all 0 0 0 0 0 0 0 0 0
  • 自定义Switch背景带文字

    需要实现的效果 标题代码实现 div class custom switch span class custom left 关灯 span div class switch btn div span class custom right 开
  • mysql thread_MySQL thread_stack连接线程的优化

    MySQL连接不仅能通过网络方式 还可以通过命名管道的方式 不论是哪种方式连接MySQL 在MySQL中都是通过线程的方式管理所有客户端请求的 每一个客户端连接都会有一个与之对应的连接线程 在MySQL中实现了一个Thread Cache池
  • MySQL8高级优化,持续更新......

    索引 索引可以高效获取数据 避免对数据进行全盘扫描 查询速度很慢 索引就是一种数据结构 树 MySQL官方对索引的定义为 索引 index 是帮助MySQL高效获取数据的数据结构 有序 在数据之外 数据库系统还维护者满足特定查找算法的数据结
  • python 线性回归 统计检验 p值_使用Python进行统计建模

    点击上方 早起python 关注早起 和我一起 成为更好的自己 前言 大家好 在 之前的文章中 我们已经讲解了很多Python数据处理的方法比如 读取数据 缺失值处理 数据降维等 也介绍了一些数据可视化的方法如 Matplotlib pye
  • 电脑出现不停刷新即Windows资源管理器不停重启的情况(win10)

    电脑出现不停刷新即Windows资源管理器不停重启的情况 win10 一 现象 电脑出现不停刷新的情况 打开任务管理器发现 Windows资源管理器 进程占用很高的CPU又降下去 反复出现 二 解决方案 1 win R 在输入框中输入reg
  • PhD新生规划知乎、一亩三分地观点摘抄

    1 thesis 68 封私信 80 条消息 对 PhD 一年级新生有什么建议 知乎 zhihu com 我觉得一个优秀的phd应该是这样的 整个phd期间就发有限的几篇 然后这几篇文章就像沙滩上的脚印一样 围成了一个圈或者一个区域 这个圈
  • 解决uniapp 报错 chunk-vendors.js:25968 GET http://localhost:8080/sockjs-node/info?t=15996357

    在目录中新建一个package lock json 然后在里面添加 sockjs dev false sockjs client dev false
  • FISCO BCOS 一、搭建第一个区块链网络(及配置控制台)

    1 搭建单群组FISCO BCOS联盟链 本节以搭建单群组FISCO BCOS链为例操作 使用开发部署工具 build chain sh脚本在本地搭建一条4 节点的FISCO BCOS链 这里我用的是ubuntu20 04 第一步 安装依赖
  • 异或的巧妙用法(比较数字是否相同/独数)

    比较两个数是否相同或者在数组 该数组同一个相同数最多2个 中找出一个单独出现的数字 我们可以用异或的方法来巧妙的解决 C 代码 class Solution public int singleNumber vector
  • 《深度学习500问》一份超全深度学习资料,面试必备!

    给大家推荐一本还未完成的深度学习书籍 深度学习500问 为什么要推荐一本未完成的书 首先 这本书的作者是通过问答的形式 对常用的概率知识 线性代数 机器学习 深度学习 计算机视觉等热点问题进行阐述 清晰明了 方便检索 特别适合初学者 其次
  • Python3 PyQt5 实现文件打开及保存

    coding utf 8 Form implementation generated from reading ui file filemanage ui Created by PyQt5 UI code generator 5 12 2
  • 利用Vulnhub复现漏洞 - Imagetragick 命令执行漏洞(CVE-2016–3714)

    Imagetragick 命令执行漏洞 CVE 2016 3714 Vulnhub官方复现教程 漏洞原理 复现过程 启动环境 漏洞复现 端口设置 浏览器设置 BurpSuit设置 上传POC 反弹shell POC Vulnhub官方复现教
  • java图片透明化处理_java的图片背景透明及透明度处理

    如题 以下为通过java实现的针对图片的背景透明及透明度处理 供大家需要时参考 设置源图片为背景透明 并设置透明度 param srcFile 源图片 param desFile 目标文件 param alpha 透明度 param for
  • Required Integer parameter 'listId' is not present、JSON parse error

    目录 1 RequestParam value listId Integer id Required Integer parameter listId is not present 1 1 原因 2 将 RequestParam修改为 Re
  • 序列化和反序列化(简单)(c++)

    序列化和反序列化 简单 c 最近看了看序列化相关的 动手试着做了一下 虽然感觉自己很菜 但还是忍不住分享 由此记录成长 什么事序列化呢 我的理解 将数据转换成字节流存进内存 序列化 从指定内存取出字节流 再把字节流转换成数据 反序列化 那我