[序列化协议] --- JSON

简介: [序列化协议] --- 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

目录
相关文章
|
7天前
|
JSON 编译器 Go
Golang深入浅出之-结构体标签(Tags):JSON序列化与反射应用
【4月更文挑战第22天】Go语言结构体标签用于添加元信息,常用于JSON序列化和ORM框架。本文聚焦JSON序列化和反射应用,讨论了如何使用`json`标签处理敏感字段、实现`omitempty`、自定义字段名和嵌套结构体。同时,通过反射访问标签信息,但应注意反射可能带来的性能问题。正确使用结构体标签能提升代码质量和安全性。
10 0
|
2月前
|
JSON Java Maven
使用Jackson进行 JSON 序列化和反序列化
使用Jackson进行 JSON 序列化和反序列化
29 0
|
2月前
|
存储 JSON 安全
序列化模块pickle和json有什么区别
序列化模块pickle和json有什么区别
18 0
|
3月前
|
C++
[序列化协议] --- protobuf
[序列化协议] --- protobuf
25 0
|
3月前
|
XML 存储 API
[序列化协议] --- XML
[序列化协议] --- XML
31 0
|
3月前
|
XML JSON Linux
[序列化协议] --- 简介
[序列化协议] --- 简介
20 0
|
4月前
|
JSON Java fastjson
Java中的JSON序列化和反序列化
Java中的JSON序列化和反序列化
|
14小时前
|
JSON JavaScript Java
从前端Vue到后端Spring Boot:接收JSON数据的正确姿势
从前端Vue到后端Spring Boot:接收JSON数据的正确姿势
5 0
|
2天前
|
JSON 数据格式 Python
Python标准库中包含了json模块,可以帮助你轻松处理JSON数据
【4月更文挑战第30天】Python的json模块简化了JSON数据与Python对象之间的转换。使用`json.dumps()`可将字典转为JSON字符串,如`{&quot;name&quot;: &quot;John&quot;, &quot;age&quot;: 30, &quot;city&quot;: &quot;New York&quot;}`,而`json.loads()`则能将JSON字符串转回字典。通过`json.load()`从文件读取JSON数据,`json.dump()`则用于将数据写入文件。
8 1
|
2天前
|
JSON 数据格式 Python
Python处理JSON数据
【4月更文挑战第30天】该内容介绍了Python处理JSON数据的三个方法:1)使用`json.loads()`尝试解析字符串以验证其是否为有效JSON,通过捕获`JSONDecodeError`异常判断有效性;2)通过`json.dumps()`的`indent`参数格式化输出JSON数据,使其更易读;3)处理JSON中的日期,利用`dateutil`库将日期转换为字符串进行序列化和反序列化。
13 4