MALOUDA-PSA 2024-02-20 20:23 采纳率: 91%
浏览 2
已结题

nlohamman解析json的问题2

c++的 nlohmann 读下面json的时候,输出:

Key:childrens
Processing Json body ... ....
010
北京
86
021
上海
86
022
天津
86
023
重庆
86
Key:id
value: 86
Key:name
value: 中国
Key:parentId
value: 

其中,没有输出北京的下级内容, 中国输出到了最后面, 不知道啥原因, 还有,为什么这个json 开头和结尾是数组[]的形式? 我把这个去了,才可以正常解析:
json 内容:


[{
"id": "86",
        "name": "中国",
        "parentId": "", 
        "childrens": [
        {   
"id": "010",
    "name": "北京",
    "parentId": "86",
    "childrens": [
    {   
"id": "0101",
    "name": "朝阳区",
    "parentId": "010",
    "childrens": []
    },  
    {   
"id": "0102",
    "name": "海淀区",
    "parentId": "010",
    "childrens": []
    }   
    ]   
        },  
        {   
"id": "021",
    "name": "上海",
    "parentId": "86",
    "childrens": []
        },  
        {   
"id": "022",
    "name": "天津",
    "parentId": "86",
    "childrens": []
        },  
        {   
"id": "023",
    "name": "重庆",
    "parentId": "86",
    "childrens": []
        }   
    ]   
}]

c++ 代码:

#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include "json.hpp"

#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include "ProtocolParser.h"

#include <iostream>
#include <fstream>
#include <string>
#include <vector>

using std::cin;
using std::cout;
using std::endl;
using std::string;
using nlohmann::json;

#define filename "data.json"

bool parsejsonbody(const json& subit);
 
int main(void)
{
    ifstream file(filename, ios::in | ios::binary);
    if(!file.is_open()){
        throw runtime_error("Faile open the file.");
        }   


 json j;
    file >> j;
    file.close();

if(j.is_object()){
        for(auto& el:j.items()){
            cout << "Key:" << el.key() << endl;
        if(el.value().is_array() || el.value().is_object()){
            cout << "Processing Json body ... ...." << endl;
        parsejsonbody(el.value());
        }else if (el.value().is_string()){
            cout << "value: " << el.value().get<string>() << endl;
        }
        }
    }
  return 0;
}


bool parsejsonbody(const json& subit){
                           // for (auto &subit11 :  subit.items()){
                        if (subit.is_array()){
                            for (const auto &subItem :  subit){
                            for (auto &subit11 :  subItem.items()){
                                if (subit11.value().is_string()){
                             string vstr = subit11.value().get<string>();
                                cout << vstr <<endl;





                            }}}}else if (subit.is_object()){
//else if(subit11alue().is_string()){
                  //          cout << "subit11: " <<  *subit11 << endl;
                            for (auto &subit22 : subit.items()) {
                                if (subit22.value().is_string()){
                            string vstri = subit22.value().get<string>();
                             cout << "it key: " <<  subit22.key() << endl;
                             cout << "it value: " <<  vstri << endl;
                            } else if (subit22.value().is_array() ||  subit22.value().is_object()){
                            cout << "subit11 is array " <<   endl;
                            parsejsonbody(subit22.value());
                            }
                    }
                }
        return true;
}



  • 写回答

2条回答 默认 最新

  • GISer Liu 2024-02-20 20:24
    关注

    该回答引用自GPT-3.5,由博主GIS_Liu编写:

    根据您的描述,问题主要出在解析 JSON 数据时遗漏了北京的下级内容,同时中国被输出到了最后。此外,您还提到了 JSON 数据开头和结尾是数组形式的疑问。

    首先,JSON 数据开头和结尾是数组形式的原因是因为您的 JSON 数据以[ ]包裹,这表示它是一个数组。在 C++ 中使用 nlohmann 库解析 JSON 数据时,您可以选择直接解析整个 JSON 对象或者针对其中的特定部分进行解析。

    针对解析 JSON 数据时遗漏了北京的下级内容的问题,您需要检查您的解析函数。在您的代码中,parsejsonbody函数似乎只处理了数组和对象的情况,但没有对包含在数组中的对象进行递归处理。因此,当处理北京的下级内容时,函数没有正确地遍历其子项。您需要确保在遇到数组或对象时,递归调用parsejsonbody函数来处理其子项。

    针对中国被输出到最后的问题,这可能是因为您的代码逻辑导致了最外层的对象最后被处理。您需要确保在遍历 JSON 对象时,按照预期的顺序处理其子项,以保证输出的顺序正确。

    下面是您可能需要修改的代码部分:

    bool parsejsonbody(const json& subit) {
        if (subit.is_array()) {
            for (const auto& subItem : subit) {
                // 递归处理数组中的对象
                parsejsonbody(subItem);
            }
        } else if (subit.is_object()) {
            for (auto& subit22 : subit.items()) {
                if (subit22.value().is_string()) {
                    string vstri = subit22.value().get<string>();
                    cout << "it key: " << subit22.key() << endl;
                    cout << "it value: " << vstri << endl;
                } else if (subit22.value().is_array() || subit22.value().is_object()) {
                    cout << "subit11 is array " << endl;
                    // 递归处理对象中的子项
                    parsejsonbody(subit22.value());
                }
            }
        }
        return true;
    }
    

    在这段修改后的代码中,我添加了对数组中的对象和对象中的子项的递归处理,以确保所有内容都能被正确解析和输出。

    请测试修改后的代码,看看是否能够正确输出您期望的结果。如果还有其他问题,请随时提出。

    如果该回答解决了您的问题,请采纳!如果没有,请参考以下方案进行修订

    用户答题指南

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论
查看更多回答(1条)

报告相同问题?

问题事件

  • 系统已结题 2月28日
  • 已采纳回答 2月20日
  • 创建了问题 2月20日

悬赏问题

  • ¥20 机器学习能否像多层线性模型一样处理嵌套数据
  • ¥20 西门子S7-Graph,S7-300,梯形图
  • ¥50 用易语言http 访问不了网页
  • ¥50 safari浏览器fetch提交数据后数据丢失问题
  • ¥15 matlab不知道怎么改,求解答!!
  • ¥15 永磁直线电机的电流环pi调不出来
  • ¥15 用stata实现聚类的代码
  • ¥15 请问paddlehub能支持移动端开发吗?在Android studio上该如何部署?
  • ¥20 docker里部署springboot项目,访问不到扬声器
  • ¥15 netty整合springboot之后自动重连失效