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

Jsoncpp如何读取JSON文件中的数组?运行抛出Json::LogicError异常如何解决

问题原因及解决方法

错误点梳理

  • 根节点键名不匹配:你的JSON文件根节点下的数组键是ID,但代码中错误访问了不存在的data键,访问空的Json::Value会直接抛出LogicError异常。
  • JSON结构访问逻辑错误:ID对应的是数组类型,数组的每一项才是包含数字字符串键("1"、"2")的对象,不能直接通过root["ID"][to_string(ID)]访问,需要先定位到数组内对应ID的对象。
  • 取值方法错误:Json::FastWriter::write是将Json值序列化为JSON格式字符串,会自动给字符串值添加双引号,你需要的是直接取字符串原生值,应该调用asString()方法。
  • 缺少必要的异常校验:没有校验文件是否打开成功、JSON解析是否成功、对应键是否存在,任意一步出错都会导致后续访问抛异常。

修正后的代码

Person choosePerson(int ID)
{
    Person person;
    person.id = ID;
    ifstream file("People.json");
    // 先校验文件是否成功打开
    if (!file.is_open()) {
        throw runtime_error("无法打开People.json文件");
    }

    Json::Value root;
    Json::Reader reader;
    bool parseSuccess = reader.parse(file, root);
    // 校验JSON解析是否成功
    if (!parseSuccess) {
        throw runtime_error("JSON解析失败:" + reader.getFormattedErrorMessages());
    }

    string idStr = to_string(ID);
    // 遍历ID数组查找对应ID的条目
    for (const auto& item : root["ID"]) {
        if (item.isMember(idStr)) {
            const auto& personInfo = item[idStr];
            person.name = personInfo["name"].asString();
            person.favFood = personInfo["favouriteFood"].asString();
            person.gender = personInfo["gender"].asString();
            file.close();
            return person;
        }
    }
    // 没找到对应ID时抛出明确异常
    throw runtime_error("未找到ID为" + idStr + "的用户信息");
}

额外优化建议

如果可以调整JSON结构的话,建议把ID数组直接改成对象,键就是用户ID,不用嵌套一层对象,访问会更方便,修改后的JSON参考:

{
  "ID": {
    "1": {
      "name": "Fred",
      "favouriteFood": "Cheese",
      "gender": "Male"
    },
    "2": {
      "name": "Bob",
      "favouriteFood": "Cake",
      "gender": "Male"
    }
  }
}

改完之后就不用遍历数组,直接root["ID"][idStr]["name"].asString()就能取值,性能更好逻辑也更简单。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.24 04:57:04