C++中结构体和Json字符串互转的问题详解

大家有没有在项目中遇到过,将一些预定义的本地结构体转换为Json字符串后,发送到网络中的情形。那我猜想下大家常规的做法:写一个函数,传入结构体的指针,然后在函数中对结构体的每一个成员根据其类型,使用Json类库的赋值方法,直接或间接创建Json子对象,组成一个内存树状结构,最后调用Json类库的方法生成字符串。这样的做法似乎比较完美,工作完成得很好,确实也挑不出什么毛病来,让我们先看看在golang中是怎么做的:

type Person struct {
 Name string
 Age int
}

person1 := Person {
 Name : "abc123",
 Age : 20,
}

// Json序列化
data, _ := json.Marshal(&person1)

就一行代码,使用起来十分清爽。

而在C++的实现是这样的:

struct SPerson
{
 std::string strName;
 int nAge;
};

SPerson person1 = {
 .strName = "abc123",
 .nAge = 20,
};

Json::Value jsPerson1;
jsPerson1["name"] = person1.strName;
jsPerson1["age"] = person1.nAge;

std::string strPerson1 = jsPerson1.toStyledString();

虽然这里也只多出了3行代码,但是如果结构体比较复杂呢,我们不得不把精力陷入到其类成员变量的解析之中,而且一不小心还特别容易犯错。然而golang就没有这个问题,无论结构体多么复杂,我们始终只需要敲一行代码。这是因为golang在语言层面支持结构体动态反射,因而可以写基础库去探析其内部组成,由库来统一完成成员变量的解析工作。c++不支持反射,能想点办法不?

我们可以参考DSMarshal序列化的思想,让结构体自己管理成员的插入与提取,请看下面的做法:

 struct SPerson
   : public dakuang::JsonMarshallable
 {
  std::string strName;
  int nAge;
  bool bMale;
  std::vector<std::string> vecFriend;
  std::vector<int> vecOther;

  virtual void marshal(Json::Value & js) const
  {
   using namespace dakuang;
   js["name"] << strName;
   js["age"] << nAge;
   js["male"] << bMale;
   js["friends"] << vecFriend;
   js["others"] << vecOther;
  }
  virtual void unmarshal(const Json::Value & js)
  {
   using namespace dakuang;
   js["name"] >> strName;
   js["age"] >> nAge;
   js["male"] >> bMale;
   js["friends"] >> vecFriend;
   js["others"] >> vecOther;
  }
 };

 SPerson person1;
 person1.strName = "abc123";
 person1.nAge = 20;
 person1.bMale = true;
 person1.vecFriend = {"a", "b", "c"};
 person1.vecOther = {1, 2, 3};

 Json::Value jsPerson1;
 person1.marshal(jsPerson1);
 std::string strPerson1 = jsPerson1.toStyledString();
 qDebug("person1 => %s", strPerson1.c_str());

 SPerson person2;
 person2.unmarshal(jsPerson1);

上面代码输出:

person1 => {
   "age" : 20,
   "friends" : [ "a", "b", "c" ],
   "male" : true,
   "name" : "abc123",
   "others" : [ 1, 2, 3 ]
}

以上代码需要引入头文件jsonmarshal.h,我在其中实现了各种常规数据结构和Json对象的互相转化方法,我已将代码提交到 https://github.com/kdjie/dsmarshal,有兴趣的朋友可以参考。

总结

到此这篇关于C++中结构体和Json字符串互转问题的文章就介绍到这了,更多相关C++结构体和Json字符串互转内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!

(0)

相关推荐

  • C++中结构体和Json字符串互转的问题详解

    大家有没有在项目中遇到过,将一些预定义的本地结构体转换为Json字符串后,发送到网络中的情形.那我猜想下大家常规的做法:写一个函数,传入结构体的指针,然后在函数中对结构体的每一个成员根据其类型,使用Json类库的赋值方法,直接或间接创建Json子对象,组成一个内存树状结构,最后调用Json类库的方法生成字符串.这样的做法似乎比较完美,工作完成得很好,确实也挑不出什么毛病来,让我们先看看在golang中是怎么做的: type Person struct { Name string Age int

  • 详解Go语言中结构体与JSON间的转换

    目录 前言 结构体转 JSON JSON 解析结构体 小结 前言 在日常开发中,我们往往会将 JSON 解析成对应的结构体,反之也会将结构体转成 JSON.接下来本文会通过 JSON 包的两个函数,来介绍 JSON 与结构体之间的转换. 结构体转 JSON Marshal(v any) ([]byte, error):将 v 转成 JSON 数据,以 []byte 的形式返回. import ( "encoding/json" "fmt" ) type User s

  • C#实现文件与字符串互转的方法详解

    目录 实现功能 开发环境 实现代码 实现效果 嗯,就是BASE64,不用多想,本来计划是要跟上一篇字符串压缩一起写的,用来实现将一个文件可以用json或者text等方式进行接口之间的传输,为了保证传输效率,所以对生成的字符串进行进一步压缩.但是由于不能上传完整源代码,所以就还是分开写了,方便展示实现效果以及功能的单独使用. 实现功能 将文件与为字符串互转 开发环境 开发工具: Visual Studio 2013 .NET Framework版本:4.5 实现代码 //选择文件路径 privat

  • javascript中json对象json数组json字符串互转及取值方法

    今天用到了json数组和json对象和json类型字符串之间互转及取值,记录一下: 1.json类型的字符串转换为json对象及取值 var jsonString = '{"bar":"property","baz":3}'; var jsObject = JSON.parse(jsonString); //转换为json对象 alert(jsObject.bar); //取json中的值  2.json对象转为json类型的字符串 var js

  • Golang中结构体映射mapstructure库深入详解

    目录 mapstructure库 字段标签 内嵌结构 未映射字段 Metadata 弱类型输入 逆向转换 解码器 示例 在数据传递时,需要先编解码:常用的方式是JSON编解码(参见<golang之JSON处理>).但有时却需要读取部分字段后,才能知道具体类型,此时就可借助mapstructure库了. mapstructure库 mapstructure可方便地实现map[string]interface{}与struct间的转换:使用前,需要先导入库: go get github.com/m

  • golang结构体与json格式串实例代码

    具体代码如下所示: package main import ( "encoding/json" "fmt" ) type IT struct { //一定要注意这里的成员变量的名字首字母必须是大写 Company string Subjects []string Isok bool Price float64 } func main() { s := IT{"zyg", []string{"go", "python&

  • C与C++中结构体的区别

    C中的结构体和C++中结构体的不同之处:在C中的结构体只能自定义数据类型,结构体中不允许有函数,而C++中的结构体可以加入成员函数. C++中的结构体和类的异同: 一.相同之处:结构体中可以包含函数:也可以定义public.private.protected数据成员:定义了结构体之后,可以用结构体名来创建对象.但C中的结构体不允许有函数:也就是说在C++当中,结构体中可以有成员变量,可以有成员函数,可以从别的类继承,也可以被别的类继承,可以有虚函数. 二.不同之处:结构体定义中默认情况下的成员是

  • Go语言中结构体方法副本传参与指针传参的区别介绍

    GO语言结构体方法跟结构体指针方法的区别 首先,我定了三个接口.一个结构和三个方法: type DeptModeA interface { Name() string SetName(name string) } type DeptModeB interface { Relocate(building string, floor uint8) } type Dept struct { name string building string floor uint8 Key string } fun

  • C语言中结构体、联合体的成员内存对齐情况

    前言 最近项目进行中,遇到一个小问题,在数据协议传输过程中,我为了方便解析,就定义了一个结构体,在数据的指针传入函数的时候,我用定义好的结构体进行强制转化,没想到一直解析失败,调试很久,终于反应过来,在用结构体指针对数据强制转换时,定义结构体我没有注意到数据对齐,因为在底层实现中,我传入的数据buffer是排列整齐的,而强制转化的结构体格式中,我定义的时候没有使用__attribute__((__packed__))或者__packed强制数据对齐,导致结构体成员真实排列会按照成员中最大的变量的

  • C语言中结构体和共用体实例教程

    目录 一.实验目的 二.实验内容 三.实验记录 3.1 候选人选票统计 3.2 print函数 3.3 链表 总结 一.实验目的 掌握结构体类型变量的定义和使用: 掌握结构体类型数组的概念和应用: 掌握链表的概念,初步学会对链表进行操作: 掌握共用体的概念与使用: 掌握指向结构体变量的指针. 掌握指向结构体数组的指针的应用. 二.实验内容 编写下列程序,然后上机调试运行. 对候选人得票的统计程序.设有3个候选人,每次输入一个得票的候选人的名字,要求最后输出各人得票结果. 编写一个函数print,

随机推荐