You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何用RapidJson C++解析数组型JSON为对象列表(无需循环)

用RapidJSON解析数组开头的JSON为C++对象列表

没问题,我来帮你搞定这个RapidJSON解析数组的问题!虽然RapidJSON没有像NewtonSoft那样直接提供ToObjectList()或ToList()的现成方法,但我们可以自己封装一个简洁的模板函数,让调用体验和你想要的一样清爽,不用手动写重复的遍历代码。

步骤1:定义对应JSON结构的C++结构体

首先,我们需要创建一个和JSON字段一一对应的结构体,用来存储每个数组元素的数据:

#include <rapidjson/document.h>
#include <vector>
#include <string>
#include <cstdio>

// 与JSON字段匹配的结构体,字段名可以自定义,只要解析时对应正确即可
struct TradeData {
    double C;
    int CO;
    double H;
    double L;
    double O;
    int64_t T;  // 注意数值范围,用int64_t避免溢出
    int64_t TO;
    int V;
};

步骤2:封装解析数组到对象列表的模板函数

这个模板函数会帮你处理遍历逻辑,对外只需要传入RapidJSON的数组对象和目标结构体类型,就能直接得到对象列表:

// 模板函数:将RapidJSON数组转换为C++对象列表,相当于你想要的ToList()
template<typename T>
std::vector<T> ParseJsonArrayToObjectList(const rapidjson::Value& array) {
    std::vector<T> result;
    // 先判断输入是否为数组类型
    if (!array.IsArray()) {
        return result;
    }

    // 内部遍历数组元素,解析为结构体对象(调用时无需关心这部分逻辑)
    for (const auto& item : array.GetArray()) {
        T obj;
        // 逐个字段解析,确保字段类型与JSON中的类型匹配
        obj.C = item["C"].GetDouble();
        obj.CO = item["CO"].GetInt();
        obj.H = item["H"].GetDouble();
        obj.L = item["L"].GetDouble();
        obj.O = item["O"].GetDouble();
        obj.T = item["T"].GetInt64();
        obj.TO = item["TO"].GetInt64();
        obj.V = item["V"].GetInt();
        
        result.push_back(obj);
    }
    return result;
}

步骤3:调用示例,一步获取对象列表

现在你可以像调用现成的ToList()方法一样,轻松把JSON数组转换成C++对象列表:

int main() {
    // 你的原始JSON字符串
    const std::string json_str = R"([{ "C": 28563.0, "CO": 0, "H": 28563.0, "L": 28545.0, "O": 28547.0, "T": 1562907600, "TO": 41315958, "V": 1447 }, { "C": 28499.0, "CO": 0, "H": 28564.0, "L": 28494.0, "O": 28563.0, "T": 1562911200, "TO": 371724821, "V": 13030 }, { "C": 28516.0, "CO": 0, "H": 28536.0, "L": 28481.0, "O": 28499.0, "T": 1562914800, "TO": 301700826, "V": 10582 }, { "C": 28539.0, "CO": 0, "H": 28545.0, "L": 28500.0, "O": 28517.0, "T": 1562918400, "TO": 150871685, "V": 5290 }])";

    rapidjson::Document doc;
    // 解析JSON字符串
    doc.Parse(json_str.c_str());

    // 处理解析错误
    if (doc.HasParseError()) {
        printf("JSON解析错误,错误码:%u\n", doc.GetParseError());
        return 1;
    }

    // 一步得到对象列表,完全不用手动遍历!
    std::vector<TradeData> trade_list = ParseJsonArrayToObjectList<TradeData>(doc);

    // 验证解析结果,比如打印第一个元素
    if (!trade_list.empty()) {
        const auto& first_trade = trade_list[0];
        printf("第一个交易数据:\n");
        printf("C: %.1f, CO: %d, H: %.1f, L: %.1f\n", first_trade.C, first_trade.CO, first_trade.H, first_trade.L);
        printf("O: %.1f, T: %lld, TO: %lld, V: %d\n", first_trade.O, first_trade.T, first_trade.TO, first_trade.V);
    }

    return 0;
}

额外注意事项

  • 确保你的RapidJSON版本支持range-based for循环(较新版本都支持,如果用旧版本,可以改用迭代器遍历array.Begin()到array.End())
  • 如果JSON中存在可选字段,可以在解析前添加判断,比如if (item.HasMember("C") && item["C"].IsDouble()),避免空指针或类型不匹配错误
  • 字段类型要和JSON中的数值类型严格对应,比如T和TO是较大的整数,用int64_t防止溢出

内容的提问来源于stack exchange,提问作者Tim

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.13 09:15:47