C++使用nlohmann的简单示例

备注:本文展示一个使用nlohmann的简单示例,仅供参考,这是示例代码,非常简略,只是为了初学者方便学习使用。

本示例使用CLion创建工程,直接在工程代码中引入nlohmann,将其放在本工程的中

1, 目录结构

在这里插入图片描述
下载地址:
https://github.com/nlohmann/json/tree/develop/single_include/nlohmann/json.hpp

2,CMakeLists.txt文件

cmake_minimum_required(VERSION 3.21)
project(nlohmanndemo)

set(CMAKE_CXX_STANDARD 14)

include_directories( CMAKE_CURRENT_SOURCE_DIR/nlohmann)

add_executable(nlohmanndemo main.cpp)

3,main.cpp文件

#include <iostream>

#include "nlohmann/json.hpp"
using nlohmann::json;


struct VersionData
{
    int64_t id;
    int32_t version;
    std::string url;
    std::string name;
    // 输出运算符重载
    friend std::ostream &operator<<( std::ostream &output, const VersionData &obj)
    {
        output << "id:" << obj.id << "Version:" << obj.version ;
        return output;
    }
};

int main() {

    std::string response_body = "[\n"
                                "    {\n"
                                "        \"name\": \"project1\",\n"
                                "        \"extra_data\": {\n"
                                "            \"desc\": \"comment1\"\n"
                                "        },\n"
                                "        \"url\": \"https://a.b.c.0.zip\",\n"

                                "        \"id\": 100000,\n"
                                "        \"version\": 4\n"
                                "    }\n,"
                                "    {\n"
                                "        \"name\": \"projectB\",\n"
                                "        \"extra_data\": {\n"
                                "            \"desc\": \"comment2\",\n"
                                "            \"author\": \"zhangsan\"\n"
                                "        },\n"
                                "        \"url\": \"https://a.b.c/1.zip\",\n"
                                "        \"id\": 200000,\n"
                                "        \"version\": 5\n"
                                "    }"
                                "]";
    nlohmann::json response_json = nlohmann::json::parse(response_body, nullptr, false);
    std::vector<VersionData> versionDataList;
    if(response_json.is_array()) {
        std::cout << "array!" << std::endl;
        for (auto p : response_json) {
            VersionData versionData;
            versionData.version = p["version"];
            versionData.id = p["id"];
            versionData.name = p["name"];
            versionData.url = p["url"];
            versionDataList.push_back(versionData);

            std::cout << "id:" << versionData.id << std::endl;
        }
        std::cout << "versionDataList:" << std::endl;
        for (std::vector<VersionData>::iterator iter = versionDataList.begin(); iter != versionDataList.end(); iter++) {
            std::cout << (*iter).id << std::endl;
            std::cout << (*iter) << std::endl;
        }
    } else {
        std::cout << "not array" << std::endl;
    }

    std::cout << "done of end!" << std::endl;
    return 0;
}

4, 执行结果

cmake .
make
./nlohmanndemo

xxx-MacBook-Pro nlohmanndemo % cmake .
-- Configuring done
-- Generating done
-- Build files have been written to: xxx/CLionProjects/nlohmanndemo
xxx-MacBook-Pro nlohmanndemo % make
Consolidate compiler generated dependencies of target nlohmanndemo
[ 50%] Building CXX object CMakeFiles/nlohmanndemo.dir/main.cpp.o
[100%] Linking CXX executable nlohmanndemo
[100%] Built target nlohmanndemo
xxx-MacBook-Pro nlohmanndemo % ./nlohmanndemo 
array!
id:100000
id:200000
versionDataList:
100000
id:100000Version:4
200000
id:200000Version:5
done of end!

<think>好的,我现在需要帮助用户解决在C++中没有使用nlohmann/json库的情况下如何解析JSON并提取数据到map的问题。首先,用户之前已经得到了一个使用nlohmann/json的示例,但现在他们可能无法使用这个库,需要替代方案。 用户的问题可能源于几个方面:项目环境限制不允许使用第三方库,或者他们需要轻量级的解决方案,或者他们不熟悉如何集成nlohmann/json。我需要提供不依赖该库的方法,同时确保解决方案可行且易于理解。 首先,我应该考虑C++标准库中是否有可用的JSON解析工具。但C++标准库本身不支持JSON解析,所以需要其他方法。接下来想到的是使用第三方库,比如RapidJSON或JsonCpp,这些是常见的替代方案。用户可能不知道这些库,或者需要指导如何集成它们。 然后,用户可能希望手动解析JSON,但这对于复杂的JSON结构来说比较困难,容易出错,特别是对于嵌套对象或数组。不过,如果JSON结构简单,比如用户提供的示例中的数组,每个元素包含几个键值对,手动解析可能可行,但需要处理字符串操作和类型转换。 接下来需要分步骤思考如何解决这个问题。首先,确认用户是否愿意使用其他第三方库,或者必须完全使用标准库。如果用户接受其他库,推荐RapidJSON或JsonCpp,并提供示例代码。如果必须使用标准库,可能需要手动解析,但需要警告其局限性。 另外,用户可能需要代码示例,所以需要准备使用不同库的示例,比如RapidJSON和JsonCpp,以及手动解析的简单例子。同时,注意代码的正确性和可读性,确保用户能够理解每一步的操作。 还需要考虑错误处理,比如JSON格式不正确时的异常处理,或者键不存在的情况。用户可能在实际应用中遇到这些问题,所以代码示例中应该包含基本的错误检查,比如检查键是否存在,或者值类型是否正确。 最后,总结不同方法的优缺点,帮助用户根据他们的具体情况选择最合适的方案。例如,第三方库更强大但需要集成,手动解析适合简单需求但不够健壮。 现在,我需要将上述思考整理成一个结构清晰的回答,分步骤介绍不同的解决方案,并提供代码示例和注意事项。确保使用中文,语言口语化,避免技术术语过于复杂,同时保持专业性。</think>当无法使用nlohmann/json时,可以通过以下方法在C++中实现JSON到map的转换: $$ \text{替代方案} = \begin{cases} \text{其他JSON库} & \text{推荐方案} \\ \text{手动解析} & \text{简易场景} \\ \text{系统API} & \text{Windows平台特有} \end{cases} $$ 一、主流JSON库替代方案 1. RapidJSON(高性能)示例: ```cpp #include "rapidjson/document.h" #include <map> std::map<uint32_t, uint32_t> parse_with_rapidjson(const char* json) { rapidjson::Document doc; doc.Parse(json); std::map<uint32_t, uint32_t> mapping; for (auto& item : doc.GetArray()) { mapping.emplace( item["BKQJID"].GetUint(), item["ZKQJID"].GetUint() ); } return mapping; } ``` 2. JsonCpp(易用性佳)示例: ```cpp #include <json/json.h> #include <fstream> std::map<int, std::string> parse_with_jsoncpp() { Json::Value root; std::ifstream config("data.json"); config >> root; std::map<int, std::string> result; for (auto& item : root) { result[item["id"].asInt()] = item["name"].asString(); } return result; } ``` 二、纯标准库方案(简易解析) 适用于简单键值对结构: ```cpp #include <map> #include <string> #include <sstream> std::map<std::string, std::string> manual_parse(const std::string& json) { std::map<std::string, std::string> result; std::istringstream iss(json.substr(1, json.size()-2)); // 去除外围{} std::string pair; while (std::getline(iss, pair, ',')) { size_t colon = pair.find(':'); std::string key = pair.substr(1, colon-2); // 去除引号 std::string value = pair.substr(colon+3, pair.size()-colon-4); result[key] = value; } return result; } /* 输入示例:{"key1":"value1","key2":"value2"} */ ``` 三、Windows平台特有方法 使用COM组件解析: ```cpp #include <comutil.h> #pragma comment(lib, "comsuppw.lib") void parse_with_com() { CoInitialize(NULL); IStream* stream = /* 创建流对象 */; CComPtr<IXMLDOMDocument> doc; doc.CoCreateInstance(CLSID_DOMDocument); doc->load(CComVariant(stream)); CComPtr<IXMLDOMNodeList> nodes; doc->selectNodes(L"//items/item", &nodes); // 后续遍历节点提取数据... } ``` 四、方案对比分析表 | 特性 | RapidJSON | JsonCpp | 手动解析 | COM组件 | |--------------------|-----------|---------|----------|---------| | 依赖项 | 头文件库 | 需编译 | 无 | Windows | | 标准符合度 | RFC7159 | 较好 | 有限 | 自定义 | | 处理速度 | ★★★★★ | ★★★☆ | ★★☆ | ★★★☆ | | 内存占用 | 低 | 中 | 可变 | 高 | | 开发便捷性 | 中等 | 高 | 低 | 低 | 五、选择建议流程 ```mermaid graph TD A[需求分析] --> B{数据结构复杂度} B -->|简单键值对| C[手动解析] B -->|嵌套结构| D{性能要求} D -->|高吞吐量| E[RapidJSON] D -->|易用优先| F[JsonCpp] A --> G{运行环境} G -->|Windows应用| H[COM方案] ``` 实际开发建议: 1. 库集成方法: - RapidJSON:直接将`include/rapidjson`目录复制到项目 - JsonCpp:使用vcpkg安装 `vcpkg install jsoncpp` 2. 错误处理模板: ```cpp try { auto data = parse_json(input); } catch (const std::exception& e) { std::cerr << "解析错误: " << e.what() << "\n原始数据: " << input.substr(0, 50) << "..."; return ERROR_CODE; } ``` 3. 性能优化技巧: ```cpp // 预分配内存(适用于vector存储方案) result.reserve(estimated_size
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值