[序列化协议] --- JSON

本文涉及的产品
全局流量管理 GTM,标准版 1个月
云解析 DNS,旗舰版 1个月
公共DNS(含HTTPDNS解析),每月1000万次HTTP解析
简介: [序列化协议] --- JSON

1. json的基础语法和规范

1.1 json是什么

- JSON 指的是 JavaScript 对象表示法(JavaScript Object Notation)
- JSON 是轻量级的文本数据交换格式
- JSON 独立于语言:JSON 使用 Javascript语法来描述数据对象,但是 JSON 仍然独立于语言和平台。JSON 解析器和 JSON 库支持许多不同的编程语言。 目前非常多的动态(PHP,JSP,.NET)编程语言都支持JSON。
- JSON 具有自我描述性,更易理解

1.2 JSON基本语法规则

  • 数据在名称/值对中
  • 数据由逗号分隔
  • 大括号 {} 保存对象
  • 中括号 [] 保存数组,数组可以包含多个对象

JSON的值可以是:

  • 数字(整数或浮点数)
  • 字符串(在双引号中)
  • 逻辑值(true 或 false)
  • 数组(在中括号中)
  • 对象(在大括号中)
  • null

给出一个简单的JSON格式文件示例

{
    "sites": [
        { "name":"菜鸟教程" , "url":"www.runoob.com" }, 
        { "name":"google" , "url":"www.google.com" }, 
        { "name":"微博" , "url":"www.weibo.com" }
    ],
    "flag" : true
}

2. 使用JSONcpp开源库解析JSON文件

2.1 jsoncpp源码下载

直接在github搜索jsoncpp即可。给出下载连接:https://github.com/open-source-parsers/jsoncpp

2.2 具体配置步骤

1> 解压源码

2> 在源码目录的上一层新建build目录,用来保存编译过程生成的中间文件

3> 在build目录执行cmake …

4> 在build目录执行make

5> 在build目录下执行make install

查看安装在本地的jsoncpp库

ls /usr/local/include ls/usr/local/lib

将编译生成的头文件,还有.so文件放在项目中,可以直接使用jsoncpp的库函数。

我这里已经写好了一个示例项目https://github.com/yum9193/json_cpp_usage

3. 关于jsoncpp库的使用简介

使用jsoncpp有两种方法

方法一:使用Jsoncpp生成的lib文件

解压上面下载的Jsoncpp文件,在jsoncpp默认生成静态链接库。 在工程中引用,只需要包含include/json下的头文件及生成的.lib文件即可。

方法二:使用Jsoncpp包中的.cpp和.h文件

解压上面下载的Jsoncpp文件,把jsoncpp-src-0.5.0文件拷贝到工程目录下,将jsoncpp-src-0.5.0\jsoncpp-src-0.5.0\include\json和jsoncpp-src-0.5.0\jsoncpp-src-0.5.0\src\lib_json目录里的文件包含到VS工程中,在VS工程的属性C/C++下General中Additional Include Directories包含头文件目录.\jsoncpp-src-0.5.0\include。在使用的cpp文件中包含json头文件即可,如:#include “json/json.h”。将json_reader.cpp、json_value.cpp和json_writer.cpp三个文件的Precompiled Header属性设置为Not Using Precompiled Headers,否则编译会出现错误。

jsoncpp 使用详解

jsoncpp 主要包含三种类型的 class:Value、Reader、Writer。jsoncpp 中所有对象、类名都在 namespace Json 中,包含 json.h 即可。

Json::Value 只能处理 ANSI 类型的字符串,如果 C++ 程序是用 Unicode 编码的,最好加一个 Adapt 类来适配。

4. 使用c++读取json文件示例

demo.json文件【源码直接抄录自https://blog.csdn.net/shuiyixin/article/details/89330529

{
   "age" : 21,
   "friends" : {
      "friend_age" : 21,
      "friend_name" : "ZhaoWuxian",
      "friend_sex" : "man"
   },
   "hobby" : [ "sing", "run", "Tai Chi" ],
   "name" : "shuiyixin",
   "sex" : "man"
}

test.cpp文件

#include <iostream>
#include <json/json.h>
#include <fstream>
using namespace std;
void readFileJson()
{
        Json::Reader reader;
        Json::Value root;
        //从文件中读取,保证当前文件有demo.json文件  
        ifstream in("demo.json", ios::binary);
        if (!in.is_open())
        {
                cout << "Error opening file\n";
                return;
        }
        if (reader.parse(in, root))
        {
                //读取根节点信息  
                string name = root["name"].asString();
                int age = root["age"].asInt();
                string sex = root["sex"].asString();
                cout << "My name is " << name << endl;
                cout << "I'm " << age << " years old" << endl;
                cout << "I'm a " << sex << endl;
        
        //读取子节点信息  
                string friend_name = root["friends"]["friend_name"].asString();
                int friend_age = root["friends"]["friend_age"].asInt();
                string friend_sex = root["friends"]["friend_sex"].asString();
                cout << "My friend's name is " << friend_name << endl;
                cout << "My friend's sex is "<<friend_sex << endl;
                cout << "My friend is " << friend_age << " years old" << endl;
                //读取数组信息  
                cout << "Here's my hobby:" << endl;
                for (unsigned int i = 0; i < root["hobby"].size(); i++)
                {
                        string ach = root["hobby"][i].asString();
                        cout << ach << '\t';
                }
                cout << endl;
                cout << "Reading Complete!" << endl;
        }
        else
        {
                cout << "parse error\n" << endl;
        }
        in.close();
}
int main(void)
{
        readFileJson();
        return 0;
}

执行结果如下:

5. 使用c++写入json文件示例

test.cpp文件:
#include <iostream>
#include <json/json.h>
#include <fstream>
using namespace std;
void writeFileJson()
{
  //根节点  
  Json::Value root;
 
  //根节点属性  
  root["name"] = Json::Value("shuiyixin");
  root["age"] = Json::Value(21);
  root["sex"] = Json::Value("man");
 
  //子节点  
  Json::Value friends;
 
  //子节点属性  
  friends["friend_name"] = Json::Value("ZhaoWuxian");
  friends["friend_age"] = Json::Value(21);
  friends["friend_sex"] = Json::Value("man");
 
  //子节点挂到根节点上  
  root["friends"] = Json::Value(friends);
 
  //数组形式  
  root["hobby"].append("sing");
  root["hobby"].append("run");
  root["hobby"].append("Tai Chi");
 
  //直接输出  
  //cout << "FastWriter:" << endl;
  //Json::FastWriter fw;
  //cout << fw.write(root) << endl << endl;
 
  //缩进输出  
  cout << "StyledWriter:" << endl;
  Json::StyledWriter sw;
  cout << sw.write(root) << endl << endl;
 
  //输出到文件  
  ofstream os;
  os.open("demo.json", std::ios::out | std::ios::app);
  if (!os.is_open())
    cout << "error:can not find or create the file which named \" demo.json\"." << endl;
  os << sw.write(root);
  os.close();
 
}
int main(void)
{
        writeFileJson();
        return 0;
}

执行结果如下:可以看到已经在目录新建了demo.json文件,并且写入成功

要注意的是:

1.如果要写入的文件不存在,会自动创建该文件;

2.如果文件存在,写入过程不会覆盖文件中原有数据,而是将新数据写在原有数据后面。

6. 解析json样式字符串

在实际项目中更多使用的是从文件解析json,从字符串解析json示例只是为了完整记录。

6.1 简单json样式字符串解析示例

#include <iostream>
#include <json/json.h>
#include <fstream>
using namespace std;
void readStrJson()
{
  //字符串  
  const char* str =
  "{\"name\":\"shuiyixin\",\"age\":\"21\",\"sex\":\"man\"}";
//  "{
//    "name" : "shuiyixin",
//    "age" : "21",
//    "sex" : "man"
//  }";
 
 
  Json::Reader reader;
  Json::Value root;
 
  //从字符串中读取数据  
  if (reader.parse(str, root))
  {
    string name = root["name"].asString();
    int age = root["nomen"].asInt();
    string sex = root["sex"].asString();
    cout << name + "," << age << "," << sex <<  endl;
  }
 
}
int main(void)
{
        readStrJson();
        return 0;
}

执行结果如下:

6.2 复杂json样式字符串解析示例

#include <iostream>
#include <json/json.h>
#include <fstream>
using namespace std;
void readStrProJson()
{
  string strValue = "{\"name\":\"shuiyixin\",\"major\":[{\"AI\":\"MachineLearning\"},{\"AI\":\"DeepLearning\"},{\"AI\":\"ComputerVision\"}]}";
  
  /*
  {
    "name":"shuiyixin",
    "major":[
    {
      "AI":"MachineLearning"
    },
    {
      "AI":"DeepLearning"
    },
    {
      "AI":"ComputerVision"
    }]
  }
  */
  
  
  Json::Reader reader;
  Json::Value value;
  if (reader.parse(strValue, value))
  {
    string out = value["name"].asString();
    cout << out << endl;
    const Json::Value arrayObj = value["major"];
    for (unsigned int i = 0; i < arrayObj.size(); i++)
    {
      out = arrayObj[i]["AI"].asString();
      cout << out<<endl;
    }
  }
}
int main(void)
{
        readStrProJson();
        return 0;
}

执行结果如下:

7. 组装json样式字符串

#include <iostream>
#include <string.h>
using namespace std;
/**
 * 拼接int
 */
std::string  getKeyValue(std::string sKey, int iValue)
{
    char szDoubleQutoes[] = "\"";
    char szColon[] = ":";
    char szValue[50] = { 0 };
    std::string strResult;
    strResult.append("{");
    strResult.append(szDoubleQutoes);
    strResult.append(sKey);
    strResult.append(szDoubleQutoes);
    strResult.append(szColon);
    sprintf(szValue, "%d", iValue);
    strResult.append(szValue);
    strResult.append("}");
    return strResult;
}
/**
 * 拼接float,保留3位
 */
std::string  getKeyValue(std::string sKey, float fValue)
{
    char szDoubleQutoes[] = "\"";
    char szColon[] = ":";
    char szValue[50] = { 0 };
    std::string strResult;
    strResult.append("{");
    strResult.append(szDoubleQutoes);
    strResult.append(sKey);
    strResult.append(szDoubleQutoes);
    strResult.append(szColon);
    sprintf(szValue, "%0.3f", fValue);
    strResult.append(szValue);
    strResult.append("}");
    return strResult;
}
/**
 * 拼接string
 */
std::string  getKeyValue(std::string sKey, std::string sValue)
{
    char szDoubleQutoes[] = "\"";
    char szColon[] = ":";
    std::string strResult;
    strResult.append("{");
    strResult.append(szDoubleQutoes);
    strResult.append(sKey);
    strResult.append(szDoubleQutoes);
    strResult.append(szColon);
    strResult.append(szDoubleQutoes);
    strResult.append(sValue);
    strResult.append(szDoubleQutoes);
    strResult.append("}");
    return strResult;
}
/**
 * 拼接object
 */
std::string  getKeyValueObject(std::string sKey, std::string sObject)
{
    char szDoubleQutoes[] = "\"";
    char szColon[] = ":";
    std::string strResult;
    strResult.append(szDoubleQutoes);
    strResult.append(sKey);
    strResult.append(szDoubleQutoes);
    strResult.append(szColon);
    strResult.append(sObject);
    return strResult;
}
/**
 * 拼接array
 */
std::string  getKeyValueArray(std::string sKey, std::string sArray)
{
    char szDoubleQutoes[] = "\"";
    char szColon[] = ":";
    std::string strResult;
    strResult.append(szDoubleQutoes);
    strResult.append(sKey);
    strResult.append(szDoubleQutoes);
    strResult.append(szColon);
    strResult.append("[");
    strResult.append(sArray);
    strResult.append("]");
    return strResult;
}
struct student
{
  int age;
  char sex[10];
  float score;
};
int main(void)
{
  student s1;
  s1.age = 20; 
  strcpy(s1.sex, "man");
  s1.score = 120.5;
  
  printf("%s\n", getKeyValue("age", s1.age).c_str());
  printf("%s\n", getKeyValue("sex", s1.sex).c_str());
  printf("%s\n", getKeyValue("score", s1.score).c_str());
  
  return 0;
}

编译输出:

参看连接:

https://blog.csdn.net/shuiyixin/article/details/89330529

https://www.cnblogs.com/liaocheng/p/4243731.html

相关文章
|
3月前
|
XML 存储 JSON
Twaver-HTML5基础学习(19)数据容器(2)_数据序列化_XML、Json
本文介绍了Twaver HTML5中的数据序列化,包括XML和JSON格式的序列化与反序列化方法。文章通过示例代码展示了如何将DataBox中的数据序列化为XML和JSON字符串,以及如何从这些字符串中反序列化数据,重建DataBox中的对象。此外,还提到了用户自定义属性的序列化注册方法。
48 1
|
16天前
|
JSON JavaScript Java
对比JSON和Hessian2的序列化格式
通过以上对比分析,希望能够帮助开发者在不同场景下选择最适合的序列化格式,提高系统的整体性能和可维护性。
21 3
|
22天前
|
JSON 数据格式 索引
Python中序列化/反序列化JSON格式的数据
【11月更文挑战第4天】本文介绍了 Python 中使用 `json` 模块进行序列化和反序列化的操作。序列化是指将 Python 对象(如字典、列表)转换为 JSON 字符串,主要使用 `json.dumps` 方法。示例包括基本的字典和列表序列化,以及自定义类的序列化。反序列化则是将 JSON 字符串转换回 Python 对象,使用 `json.loads` 方法。文中还提供了具体的代码示例,展示了如何处理不同类型的 Python 对象。
|
24天前
|
JSON JavaScript 前端开发
|
3月前
|
JSON Go 数据格式
Golang语言结构体链式编程与JSON序列化
这篇文章是关于Go语言中结构体链式编程与JSON序列化的教程,详细介绍了JSON格式的基本概念、结构体的序列化与反序列化、结构体标签的使用以及如何实现链式编程。
41 4
|
3月前
|
JSON 数据格式
序列化 json和pickle
序列化 json和pickle
|
4月前
|
存储 JSON JavaScript
python序列化: json & pickle & shelve 模块
python序列化: json & pickle & shelve 模块
|
7月前
|
XML 存储 JSON
c#XML、JSON的序列化和反序列化,看完你就懂了
c#XML、JSON的序列化和反序列化,看完你就懂了
110 0
|
7月前
|
存储 JSON JavaScript
Python中的JSON与Pickle模块:数据序列化和反序列化的利器
在Python编程中,数据的序列化和反序列化是经常遇到的操作。序列化是将数据结构或对象状态转换为可以存储或传输的格式的过程,而反序列化则是这个过程的逆操作,即将序列化的数据重新转换回原来的数据结构或对象状态。Python中的JSON和Pickle模块就是实现数据序列化和反序列化的强大工具。
|
7月前
|
JSON Java Maven
使用Jackson进行 JSON 序列化和反序列化
使用Jackson进行 JSON 序列化和反序列化
139 0