背景

  • 今天遇到了一个使用C++读取json格式文本文档的需求,在python中是十分简单的一个需求,没想到要在C++实现的时候却卡了壳弄了一个下午找不到方法,特此记录一下解决方案,供各位参考

使用库

  • cJSON

    1. cJSON是github开源的一个用于解析JSON字符串的库,相比其他库起来不需要麻烦的配置过程,只需要将一个.c文件和一个.h文件包含到源代码目录,在代码中#include"cJSON.h"即可

    2. cJSON是使用链表来存储数据的,其访问方式很像一颗树。每一个节点可以有兄弟节点,通过next/prev指针来查找,它类似双向链表;每个节点也可以有孩子节点,通过child指针来访问,进入下一层。只有节点是对象或数组时才可以有孩子节点

    3. type是键(key)的类型,一共有7种取值,分别是:False,Ture,NULL,Number,String,Array,Object。若是Number类型,则valueint或valuedouble中存储着值。若期望的是int,则访问valueint,若期望的是double,则访问valuedouble,可以得到值。若是String类型的,则valuestring中存储着值,可以访问valuestring得到值。

    4. string中存放的是这个节点的名字,可理解为key的名称

使用教程

  1. 在github上下载cJSON项目

  2. 将项目中的cJSON.ccJSON.h复制到自己的项目目录下,#include"cJSON.h"即可

  3. 示例代码

    1
    #include "cJSON.h"
    2
    #include <iostream>
    3
    #include <fstream>
    4
    #include <sstream>
    5
    #include <cstring>
    6
    using namespace std;
    7
    8
    struct JsonTest
    9
    {
    10
        int id;
    11
        char cName[32];
    12
        float fValue;
    13
    };
    14
    15
    void TestJsonObject()
    16
    {
    17
    18
        //测试cJson 创建Json对象
    19
        JsonTest jsonObject = {1, "geekCode", 0.2f};
    20
        cJSON *root, *object;
    21
        char *result; //生成的结果
    22
        int i;
    23
    24
        root = cJSON_CreateObject();
    25
    26
        object = cJSON_CreateObject();
    27
        cJSON_AddNumberToObject(object, "id", jsonObject.id);
    28
        cJSON_AddStringToObject(object, "name", jsonObject.cName);
    29
        cJSON_AddNumberToObject(object, "value", jsonObject.fValue);
    30
    31
        cJSON_AddNumberToObject(root, "id", jsonObject.id);
    32
        cJSON_AddStringToObject(root, "name", jsonObject.cName);
    33
        cJSON_AddNumberToObject(root, "value", jsonObject.fValue);
    34
        cJSON_AddItemToObject(root, "object", object);
    35
    36
        result = cJSON_Print(root);
    37
        cJSON_Delete(root);
    38
        printf("生成Json:\n%s\n", result);
    39
    40
        //解析Json对象
    41
    42
        root = cJSON_Parse(result);
    43
        if (!root)
    44
        {
    45
            printf("Error before: [%s]\n", cJSON_GetErrorPtr());
    46
            return;
    47
        }
    48
        object = cJSON_GetObjectItem(root, "object");
    49
    50
        if (!object)
    51
        {
    52
            cJSON_Delete(root);
    53
            return;
    54
        }
    55
    56
        JsonTest objectJson;
    57
        JsonTest rootJson;
    58
    59
        //解析item
    60
        cJSON *item;
    61
        printf("解析过程:\n");
    62
        //解析到objectJson
    63
        item = cJSON_GetObjectItem(object, "id");
    64
        printf("Item: type=%d, key is %s, valueint=%d\n", item->type, item->string, item->valueint);
    65
        objectJson.id = item->valueint;
    66
        item = cJSON_GetObjectItem(object, "name");
    67
        printf("Item: type=%d, key is %s, valuestring=%s\n", item->type, item->string, item->valuestring);
    68
        strcpy(objectJson.cName, item->string);
    69
        item = cJSON_GetObjectItem(object, "value");
    70
        printf("Item: type=%d, key is %s, valuedouble=%2f\n", item->type, item->string, item->valuedouble);
    71
        objectJson.fValue = item->valuedouble;
    72
    73
        //解析到rootJson
    74
        item = cJSON_GetObjectItem(root, "id");
    75
        rootJson.id = item->valueint;
    76
        item = cJSON_GetObjectItem(root, "name");
    77
        strcpy(rootJson.cName, item->string);
    78
        item = cJSON_GetObjectItem(root, "value");
    79
        rootJson.fValue = item->valuedouble;
    80
    81
        //打印解析结果
    82
        printf("解析结果:\nroot:\n");
    83
        printf("\n\tid:%d\n\tname:%s\n\tvalue:%2f\n\t\n", rootJson.id, rootJson.cName, rootJson.fValue);
    84
        printf("\tobject:\n\t\tid:%d\n\t\tname:%s\n\t\tvalue:%2f\n", objectJson.id, objectJson.cName, objectJson.fValue);
    85
    }
    86
    87
    void TestRatingJson()
    88
    {
    89
        string jsonStr;
    90
        ifstream jsonFile;
    91
        jsonFile.open("../rating.json");
    92
        stringstream jsonStream;
    93
        jsonStream << jsonFile.rdbuf();
    94
        jsonFile.close();
    95
        jsonStr = jsonStream.str();
    96
    97
        cJSON *root;
    98
        cJSON *item;
    99
        cJSON *from;
    100
        string s;
    101
        root = cJSON_Parse(jsonStr.c_str());
    102
    103
        int size = cJSON_GetArraySize(root);
    104
        for (int i = 0; i < size; i++)
    105
        {
    106
            try
    107
            {
    108
                item = cJSON_GetArrayItem(root, i);
    109
                from = cJSON_GetObjectItem(item, "from");
    110
                s = from->valuestring;
    111
                std::cout << s << std::endl;
    112
            }
    113
            catch (const std::exception &e)
    114
            {
    115
                std::cerr << e.what() << '\n';
    116
            }
    117
        }
    118
        cJSON_Delete(root);
    119
    }
    120
    121
    int main()
    122
    {
    123
        // TestJsonObject();
    124
        TestRatingJson();
    125
    }

    其中rating.json文件可以前往这里下载