代码改变世界

两种库解析、构造 JSON

2018-05-28 23:28  清晨、午后  阅读(374)  评论(0编辑  收藏  举报

1.用CJSON库

1.1解析Json

 需要解析的JSON文件:

{
    "name":"Tsybius",
    "age":23,
    "sex_is_male":true,
    "partner":
    {
        "partner_name":"Galatea",
        "partner_age":21,
        "partner_sex_is_male":false
    },
    "achievement":["ach1","ach2","ach3"]
}

 解析代码(层次解析法

/* 读取JSON格式的文件到string */
ULONG_32 TMS_C_ReadJSONFile(const std::string ostrFileName, std::string &ostrJSON)
{
    std::ifstream oInFile;
    oInFile.open(ostrFileName.data());   //将文件流对象与文件连接起来 
    std::string strText;
    while (getline(oInFile, strText))
    {
        ostrJSON += strText;
    }
    oInFile.close();

    return 0 ;
}
int main()
{
    //str 为从文件中读取到的值
    std::string str = "{\"name\":\"Tsybius\",\"age\":23,\"sex_is_male\":true,    \"partner\":{\"partner_name\":\"Galatea\",\"partner_age\":21,\"partner_sex_is_male\":false},\"achievement\":[\"ach1\",\"ach2\",\"ach3\"]}";

    //转换为整个Json
    cJSON *returnjson = cJSON_Parse(str.c_str());
    if (NULL == returnjson)
    {
        return 0;
    }

    // 获取根节点下的某个值
    cJSON * name = cJSON_GetObjectItem(returnjson, "name");
    if(NULL == name)
    {
        return 0;
    }
    std::string str1 = name->valuestring;
    std::cout << str1 << std::endl;

    // 获取子节点
    cJSON * partner = cJSON_GetObjectItem(returnjson, "partner");
    if(NULL == partner)
    {
        return 0;
    }

    // 获取子节点下的某个值
    cJSON * partner_name = cJSON_GetObjectItem(partner, "partner_name");
    if(NULL == partner_name)
    {
        return 0;
    }
    std::string str2 = partner_name->valuestring;
    std::cout << str2 << std::endl;

    // 获取子节点下的数组
    cJSON * achievement = cJSON_GetObjectItem(returnjson, "achievement");
    if(NULL == achievement)
    {
        return 0;
    }
    cJSON *pArrayItem = NULL;
    pArrayItem = cJSON_GetArrayItem(achievement, 0);
    std::string str3 = pArrayItem->valuestring;
    int i = cJSON_GetArraySize(achievement);    //获取数组大小

    cJSON_Delete(returnjson);  // 注意cJSON的内存泄漏
   system(
"pause"); return 0; }

  1.2构造Json

#include <fstream>
#include <string>
#include <vector>
#include "cJSON.h"
int main()
{
    int ulRet = 0; 
    std::string ostrJSONFilePath1 = "F:\\1.txt";
    //ulRet = TMS_C_ReadJSONFile(ostrJSONFilePath1); 

    cJSON *pJsonVehicleInfo = NULL; 
    //也可以先创建数组,然后添加元素,构造为数组对象
    pJsonVehicleInfo = cJSON_CreateObject();
    cJSON *vehicleList = NULL;
    cJSON_AddItemToObject(pJsonVehicleInfo, "MotorVehicleObjectList", vehicleList = cJSON_CreateArray());

    cJSON *subdir = NULL;

    cJSON_AddItemToArray(vehicleList, subdir = cJSON_CreateObject());

    cJSON_AddStringToObject(subdir, "MotorVehicleID", "2");
    cJSON_AddNumberToObject(subdir, "InfoKind", 3);
    cJSON_AddStringToObject(subdir, "SourceID", "4");
    cJSON_AddStringToObject(subdir, "TollgateID", "5");

    cJSON *SubImageObject = NULL;
    cJSON_AddItemToObject(subdir, "SubImageObject", SubImageObject = cJSON_CreateObject());

    cJSON *picList = NULL;
    cJSON_AddItemToObject(SubImageObject, "SubImageInfoList", picList = cJSON_CreateArray());
    cJSON *sub = NULL;
    cJSON_AddItemToArray(picList, sub = cJSON_CreateObject());
    cJSON_AddStringToObject(sub, "pic1", "pic1");
    cJSON_AddStringToObject(sub, "pic2", "pic2");
    sub = NULL;
    cJSON_AddItemToArray(picList, sub = cJSON_CreateObject());
    cJSON_AddStringToObject(sub, "pic3", "pic3");
    cJSON_AddStringToObject(sub, "pic4", "pic4");

    /* JSON转为字符串 */
    char * responeJSONbuffer = cJSON_Print(pJsonVehicleInfo);

    std::string ostrJSONFilePath = "F:\\3.txt";
    std::ofstream oOutFile;
    oOutFile.open(ostrJSONFilePath.data());
    oOutFile << responeJSONbuffer << std::endl;
    oOutFile.close();
  cJSON_Delete(pJsonVehicleInfo);  // 注意cJSON的内存泄漏,只需要释放根节点即可
system(
"pause"); return 0; }

 构造后输出的文档

{
    "MotorVehicleObjectList":    [{
            "MotorVehicleID":    "2",
            "InfoKind":    3,
            "SourceID":    "4",
            "TollgateID":    "5",
            "SubImageObject":    
            {
                "SubImageInfoList":    
                [
                    {
                        "pic1":    "pic1",
                        "pic2":    "pic2"
                    }, 
                    {
                        "pic3":    "pic3",
                        "pic4":    "pic4"
                    }
                ]
            }
        }]
}

2. 用jsoncpp.zip

2.1获取json第三方工具

下载 jsoncpp.zip ,解压后可在vs下建立新的工程进行编译,注意设置 配置熟悉》c/c++》代码生成》运行时库为MTd(使用该库的工程也这样设置),编译后将 lib 文件放入工程目录,将 jsoncpp\include整个文件放入工程中的文件(使用lib时需要引用该库文件文件的头文件)。

 2.2 从文件中解析JSON

需要解析的JSON文件:

{
    "name":"Tsybius",
    "age":23,
    "sex_is_male":true,
    "partner":
    {
        "partner_name":"Galatea",
        "partner_age":21,
        "partner_sex_is_male":false
    },
    "achievement":["ach1","ach2","ach3"]
}

方法1:整体解析法

#include <iostream>
#include <fstream>
#include "json/json.h"
using namespace std;

int main()
{
    Json::Reader reader;
    Json::Value root;
    //从文件中读取
    ifstream is;
    is.open("PersonalInfo.json", ios::binary);
    if(reader.parse(is,root))
    {
        //读取根节点信息
        string name = root["name"].asString();
        int age = root["age"].asInt();
        bool sex_is_male = root["sex_is_male"].asBool();

        //读取子节点信息
        string partner_name = root["partner"]["partner_name"].asString();
        int partner_age = root["partner"]["partner_age"].asInt();
        bool partner_sex_is_male = root["partner"]["partner_sex_is_male"].asBool();

        //读取数组信息
        cout << "Here's my achievements:" << endl;
        for(int i = 0; i < root["achievement"].size(); i++)
        {
      // 严重的bug, string ach = root["achievement"][0].asString();  写成这样无法编译,如果索引是0,则必须用变量替代
            string ach = root["achievement"][i].asString();
            cout << ach << '\t';
        }
    }
    is.close();

    system("pause");
    return 0;
}

 

  方法2:层次解析法,见CJSON库的使用

2.3将信息保存为JSON格式

code

#include <iostream>
#include <fstream>
#include "json/json.h"
using namespace std;

int main()
{
    //根节点
    Json::Value root;

    //根节点属性
    root["name"] = Json::Value("Tsybius");
    root["age"] = Json::Value(23);
    root["sex_is_male"] = Json::Value(true);

    //子节点
    Json::Value partner;

    //子节点属性
    partner["partner_name"] = Json::Value("Galatea");
    partner["partner_age"] = Json::Value(21);
    partner["partner_sex_is_male"] = Json::Value(false);

    //子节点挂到根节点上
    root["partner"] = Json::Value(partner);

    //数组形式
    root["achievement"].append("ach1");
    root["achievement"].append("ach2");
    root["achievement"].append("ach3");
    
    //数组对象
    //Json::Value array;
    //array["arr1"] =  Json::Value(1);
    //array["arr2"] =  Json::Value(2);
    //root["achievement"].append(array);    //可以直接将对象追加到数组中,构成[{...},{...}] 格式

    //直接输出
    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("PersonalInfo");
    os << sw.write(root);
    os.close();

    system("pause");
    return 0;
}

 

 保存的文件 :

{
   "achievement" : [ "ach1", "ach2", "ach3" ],
   "age" : 23,
   "name" : "Tsybius",
   "partner" : {
      "partner_age" : 21,
      "partner_name" : "Galatea",
      "partner_sex_is_male" : false
   },
   "sex_is_male" : true
}