MALOUDA-PSA 2024-02-20 12:38 采纳率: 90.1%
浏览 2
已结题

nlohamman解析json的问题

使用c++ 解析json, 输出一直是 subit11 is array, 不知道哪里出了问题?

json文件:

{
  "ver": "1.0",
  "login": {
    "user": "zhangsan",
    "pwd": "123456"
  },  
  "data": [
    {   
      "ProjName": "文件夹1-1-1-1-1",
      "FileName": "emp.cdr",
      "ProjNumber": 11, 
      "JpgFile": "emp.jpg",
      "Comments": "cdr for employee",
      "ProjType": "graphic design",
      "ProjState": 1,
      "version": 1,
      "CreateTime": "20230728",
      "UpdateTime": "20230608",
      "id": 8,
      "pid": 6
    },  
    {   
      "ProjName": "文件夹1-1-1-1-2",
      "FileName": "emp.cdr",
      "ProjNumber": 11, 
      "JpgFile": "emp.jpg",
      "Comments": "cdr for employee",
      "ProjType": "graphic design",
      "ProjState": 1,
      "version": 1,
      "CreateTime": "20230728",
      "UpdateTime": "20230608",
      "id": 7,
      "pid": 6
    },  
{
      "ProjName": "文件夹1-1-1-1",
      "FileName": "emp.cdr",
      "ProjNumber": 11,
      "JpgFile": "emp.jpg",
      "Comments": "cdr for employee",
      "ProjType": "graphic design",
      "ProjState": 1,
      "version": 1,
      "CreateTime": "20230728",
      "UpdateTime": "20230608",
      "id": 6,
      "pid": 5
    },  
    {
      "ProjName": "文件夹1-1-1",
      "FileName": "emp.cdr",
      "ProjNumber": 11,
      "JpgFile": "emp.jpg",
      "Comments": "cdr for employee",
      "ProjType": "graphic design",
      "ProjState": 1,
      "version": 1,
      "CreateTime": "20230728",
      "UpdateTime": "20230608",
      "id": 5,
      "pid": 2
    },
    {
      "ProjName": "文件夹1-2-1",
      "FileName": "emp.cdr",
      "ProjNumber": 11,
      "JpgFile": "emp.jpg",
      "Comments": "cdr for employee",
      "ProjType": "graphic design",
      "ProjState": 1,
      "version": 1,
      "CreateTime": "20230728",
      "UpdateTime": "20230608",
      "id": 4,
      "pid": 3
    },

 {
      "ProjName": "文件夹1-2",
      "FileName": "emp.cdr",
      "ProjNumber": 11,
      "JpgFile": "emp.jpg",
      "Comments": "cdr for employee",
      "ProjType": "graphic design",
      "ProjState": 1,
      "version": 1,
      "CreateTime": "20230728",
      "UpdateTime": "20230608",
      "id": 3,
      "pid": 1
    },
    {
      "ProjName": "文件夹1-1",
      "FileName": "emp.cdr",
      "ProjNumber": 11,
      "JpgFile": "emp.jpg",
      "Comments": "cdr for employee",
      "ProjType": "graphic design",
      "ProjState": 1,
      "version": 1,
      "CreateTime": "20230728",
      "UpdateTime": "20230608",
      "id": 2,
      "pid": 1
    },
    {
      "ProjName": "文件夹1",
      "FileName": "emp.cdr",
      "ProjNumber": 11,
      "JpgFile": "emp.jpg",
      "Comments": "cdr for employee",
      "ProjType": "graphic design",
      "ProjState": 1,
      "version": 1,
      "CreateTime": "20230728",
      "UpdateTime": "20230608",
      "id": 1,
      "pid": -1
    }
  ]
}
        

完整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(json submit);
 
int main(void)
{
    ifstream file(filename, ios::in | ios::binary);
    if(!file.is_open()){
        throw runtime_error("Faile open the file.");
        }   

    file.seekg(0,ios::end);
    streamsize fileSize = file.tellg();
    if(fileSize <=0){
        throw runtime_error("File is emppty");
        }   

    char *buffer = new char[fileSize];
    
    file.seekg(0,ios::beg);
    file.read(buffer, fileSize);
    cout << fileSize << "filesize" << endl;

   if(!file) {
        throw runtime_error("Reading failed or did not read all data from the file.");
        }   

    file.close();
    ProtocolParser parse;
    json j = parse.doParse(buffer);
    for (auto it = j.begin(); it != j.end(); ++it){
                    if (it->is_string()){
                    string vstr = it.value().get<string>();
                    cout << "it key: " <<  it.key() << endl;
                    cout << "it value: " <<  vstr << endl;
                    }
                    if (it->is_object()){
                    cout << "it is object " << endl;
                    }
    if (it->is_array() || it -> is_object()){
                    cout << "it is array " << endl;
            parsejsonbody(*it);
    }
    }
  return 0;
}

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


  • 写回答

1条回答 默认 最新

  • 辞轩. 2024-02-20 13:10
    关注

    以下内容来自ChatGPT 4:
    在你的C++代码中,你正尝试使用nlohmann::json库来解析一个JSON文件并打印其内容。我注意到了一些可能导致你遇到问题的地方。具体而言,问题出现在如何遍历JSON对象和数组以及如何正确引用subit11

    首先,subit11.value().is_array() || subit11.value().is_object()这一行的递归调用parsejsonbody(subit11);是不正确的。这是因为subit11是一个由subit.items()返回的迭代器项,它的类型是std::pair<const Key, Value>,因此直接传递subit11parsejsonbody函数是不合适的,应该传递subit11.value()

    其次,当你尝试打印一个字符串时,你使用了*subit11,这是不正确的,因为subit11是一个pair类型,不是指针类型,你不能对它进行解引用操作。应该使用subit11.key()来获取键,使用subit11.value()来获取值。

    以下是一些修改后的建议,旨在修正这些问题并改进代码的部分:

    #include <fstream>
    #include <iostream>
    #include <string>
    #include "json.hpp"
    
    using json = nlohmann::json;
    using namespace std;
    
    bool parsejsonbody(const json& submit);
    
    int main() {
        ifstream file("data.json");
        if (!file.is_open()) {
            cerr << "Failed to open the file." << endl;
            return 1;
        }
    
        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& submit) {
        if (submit.is_array()) {
            for (const auto& subItem : submit) {
                for (auto& subIt : subItem.items()) {
                    if (subIt.value().is_string()) {
                        cout << "Key: " << subIt.key() << " - Value: " << subIt.value().get<string>() << endl;
                    }
                }
            }
        } else if (submit.is_object()) {
            for (auto& subIt : submit.items()) {
                if (subIt.value().is_string()) {
                    cout << "Key: " << subIt.key() << " - Value: " << subIt.value().get<string>() << endl;
                } else if (subIt.value().is_array() || subIt.value().is_object()) {
                    cout << "Sub-item is a nested object or array" << endl;
                    parsejsonbody(subIt.value());
                }
            }
        }
        return true;
    }
    

    这个版本的代码进行了以下修改:

    1. 直接从文件流中解析JSON,避免了先将文件内容读入字符串再解析的步骤。
    2. parsejsonbody函数中,增加了对JSON对象和数组的递归处理逻辑。
    3. 修正了对subit11的错误引用。

    这应该会解决你遇到的“subit11 is array”一直被输出的问题,并能够正确地遍历和打印JSON文件中的所有项。

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论

报告相同问题?

问题事件

  • 系统已结题 2月28日
  • 已采纳回答 2月20日
  • 创建了问题 2月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之后自动重连失效
  • ¥15 悬赏!微信开发者工具报错,求帮改