Ask me anything
Ithy Logo
Sign in to save

使用C++解析特定结构JSON并提取数字部分的全面指南

Google end point returns JSON for long data type in quotes - Stack Overflow

在现代软件开发中,JSON(JavaScript Object Notation)作为一种轻量级的数据交换格式,广泛应用于配置文件、数据传输等场景。对于C++开发者来说,解析JSON并提取其中的数值信息是一个常见需求。本文将详细介绍如何使用不同的方法和工具在C++中解析特定结构的JSON语句,并高效地提取其中的数字部分。我们将重点关注以下几种方法:

  • 使用JsonCpp库解析JSON并提取数字
  • 利用std::regex正则表达式提取数字
  • 简单的字符串处理方法
  • 其他流行的C++ JSON库介绍

1. 使用JsonCpp库解析JSON并提取数字

JsonCpp是一个流行的C++ JSON处理库,支持解析、生成和操作JSON数据。借助该库,开发者可以方便地遍历JSON结构并提取所需的信息。以下将详细介绍如何使用JsonCpp来完成这一任务。

1.1 环境配置

1.1.1 使用包管理器安装(推荐)

如果你使用的是vcpkg作为包管理器,可以通过以下命令安装JsonCpp:

vcpkg install jsoncpp

安装完成后,记得将vcpkg集成到你的项目中。更多信息可以参考JsonCpp安装指南。

1.1.2 从源码编译安装

如果你更喜欢从源码编译,可以按照以下步骤进行:

  1. 克隆JsonCpp的GitHub仓库:

    git clone https://github.com/open-source-parsers/jsoncpp.git
  2. 进入仓库目录并创建构建目录:

    cd jsoncpp
    mkdir build
    cd build
  3. 运行CMake配置并编译:

    cmake ..
    make
    sudo make install

安装完成后,JsonCpp的头文件和库文件将被安装到系统路径中,你可以在项目中直接引用。

1.2 示例代码

以下是一个完整的C++程序示例,该程序使用JsonCpp解析特定结构的JSON字符串,并提取其中的数字部分:

#include <iostream>
#include <string>
#include <json/json.h> // 引入JsonCpp头文件

struct NumberData {
    int number;
};

void extractNumbers(const Json::Value& json, std::vector<NumberData>& numbers) {
    for (const auto& member : json.getMemberNames()) {
        const Json::Value& value = json[member];
        
        if (value.isNumeric()) {
            NumberData data;
            data.number = value.asInt();
            numbers.push_back(data);
        }
        else if (value.isObject()) {
            extractNumbers(value, numbers);
        }
        else if (value.isArray()) {
            for (const auto& element : value) {
                if (element.isNumeric()) {
                    NumberData data;
                    data.number = element.asInt();
                    numbers.push_back(data);
                }
                else if (element.isObject()) {
                    extractNumbers(element, numbers);
                }
            }
        }
    }
}

int main() {
    // 示例JSON字符串
    std::string jsonStr = R"({"key1": 10, "key2": 20, "key3": {"subKey": 30}, "key4": [40, 50]})";
    
    Json::CharReaderBuilder readerBuilder;
    Json::Value root;
    std::string errs;
    
    // 解析JSON字符串
    std::istringstream iss(jsonStr);
    if (!Json::parseFromStream(readerBuilder, iss, &root, &errs)) {
        std::cerr << "解析JSON失败: " << errs << std::endl;
        return 1;
    }
    
    // 提取数字部分
    std::vector<NumberData> numbers;
    extractNumbers(root, numbers);
    
    // 输出提取的数字部分
    for (const auto& number : numbers) {
        std::cout << "数字: " << number.number << std::endl;
    }
    
    return 0;
}

1.3 代码讲解

  1. 引入必要的头文件:

    • iostream和string是C++标准库的头文件,用于输入输出和字符串操作。
    • json/json.h是JsonCpp的头文件,包含了所有必要的JSON处理功能。
  2. 定义结构体:

    • NumberData结构体用于存储提取的数字部分。
  3. 提取数字函数:

    • extractNumbers函数递归遍历JSON对象,提取所有数字类型的值,并存储在numbers向量中。
  4. 主函数:

    • 定义一个示例JSON字符串。
    • 使用Json::CharReaderBuilder和Json::parseFromStream解析JSON字符串。
    • 调用extractNumbers函数提取数字部分。
    • 遍历并输出提取的数字。

2. 使用正则表达式提取数字

除了使用专门的JSON解析库,开发者还可以利用C++的std::regex库,通过正则表达式从JSON字符串中直接匹配和提取数字。这种方法适用于结构相对简单的JSON字符串。

2.1 示例代码

#include <iostream>
#include <string>
#include <regex>
#include <vector>

int main() {
    // 示例JSON字符串
    std::string jsonString = R"({"key1": 123, "key2": [456, 789], "key3": {"nestedKey": 101112}})";
    
    // 正则表达式,用于匹配JSON字符串中的数字
    std::regex numberRegex(R"(\b\d+\b)");
    
    // 用于存储提取出的数字
    std::vector<int> numbers;
    
    // 匹配并提取数字
    auto words_begin = std::sregex_iterator(jsonString.begin(), jsonString.end(), numberRegex);
    auto words_end = std::sregex_iterator();
    
    for (std::sregex_iterator i = words_begin; i != words_end; ++i) {
        std::smatch match = *i;
        int num = std::stoi(match.str()); // 转为整数
        numbers.push_back(num);           // 存储到结果数组
        std::cout << "提取的数字: " << num << std::endl;
    }
    
    // 输出最终提取出的数字
    std::cout << "所有提取的数字: ";
    for (const auto& num : numbers) {
        std::cout << num << " ";
    }
    std::cout << std::endl;
    
    return 0;
}

2.2 代码讲解

  1. 定义正则表达式:

    • R"(\b\d+\b)"用于匹配独立的整数数字。
    • \b表示单词边界,确保只匹配独立的数字。
    • \d+匹配一个或多个数字字符。
  2. 使用std::sregex_iterator进行匹配:

    • 遍历整个JSON字符串,找到所有匹配的数字。
    • 将匹配到的数字字符串转换为整数并存储在向量中。
  3. 输出提取结果:

    • 逐个输出提取的数字。
    • 最后统一输出所有提取的数字。

2.3 应用场景与注意事项

  • 适用于结构相对简单且数字较为独立的JSON字符串。
  • 不适用于需要区分数字类型(如整数与浮点数)或复杂嵌套结构的情况。
  • 正则表达式方法不适用于处理科学计数法表示的数字。

3. 简单的字符串处理方法

对于非常简单的JSON结构,开发者可以使用基本的字符串处理方法,如遍历字符串并提取数字。这种方法无需依赖任何第三方库,但仅适用于简易和固定格式的JSON数据。

3.1 示例代码

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

using namespace std;

// 提取数字的函数
vector<string> extractNumbers(const string& jsonStr) {
    vector<string> numbers;
    string currentNumber;
    bool isInNumber = false;
    
    for (size_t i = 0; i < jsonStr.length(); i++) {
        char c = jsonStr[i];
        
        // 检查是否是数字或小数点
        if (isdigit(c) || c == '.') {
            if (!isInNumber) {
                isInNumber = true;
                currentNumber = "";
            }
            currentNumber += c;
        }
        else {
            if (isInNumber) {
                numbers.push_back(currentNumber);
                isInNumber = false;
            }
        }
    }
    
    // 处理最后一个数字
    if (isInNumber) {
        numbers.push_back(currentNumber);
    }
    
    return numbers;
}

int main() {
    // 示例JSON字符串
    string jsonString = R"({"code":100,"data":{"value":123.45,"count":646,"items":[1,2,3]}})";
    
    cout << "原始JSON: " << jsonString << endl;
    cout << "\n提取的数字:" << endl;
    
    vector<string> numbers = extractNumbers(jsonString);
    
    for (const auto& num : numbers) {
        cout << num << endl;
    }
    
    return 0;
}

3.2 代码讲解

  1. 定义extractNumbers函数:

    • 遍历整个JSON字符串,逐字符检查是否为数字或小数点。
    • 当检测到数字字符时,开始记录当前数字。
    • 当遇到非数字字符时,将已记录的数字存入向量中。
  2. 主函数:

    • 定义一个示例JSON字符串。
    • 调用extractNumbers函数提取数字。
    • 遍历并输出提取的数字。

3.3 应用场景与限制

  • 适用于结构非常简单、数字位置固定的JSON字符串。
  • 不支持复杂嵌套或科学计数法表示的数字。
  • 缺乏类型区分,所有提取的数字均以字符串形式存储。

4. 其他流行的C++ JSON库介绍

除了,还有其他一些流行且高效的C++ JSON库,它们各有优势,适用于不同的应用场景:

4.1 nlohmann/json

nlohmann/json是一个现代化的C++ JSON库,以其简洁的接口和易用性著称。它支持C++11及以上标准,并且不依赖于其他外部库。

示例代码

#include <iostream>
#include <string>
#include <nlohmann/json.hpp> // 引入nlohmann/json头文件
#include <vector>

using json = nlohmann::json;

int main() {
    // 示例JSON字符串
    std::string jsonStr = R"(
    {
        "name": "Alice",
        "age": 30,
        "scores": {
            "math": 95,
            "english": 88,
            "science": 92
        },
        "hobbies": ["reading", "cycling", "hiking"],
        "active": true
    }
    )";
    
    // 解析JSON字符串
    json jsonData;
    try {
        jsonData = json::parse(jsonStr);
    } catch (json::parse_error& e) {
        std::cerr << "JSON解析错误: " << e.what() << std::endl;
        return 1;
    }
    
    // 提取数字部分
    std::cout << "提取的数字:" << std::endl;
    
    if (jsonData.contains("age") && jsonData["age"].is_number_integer()) {
        std::cout << "age: " << jsonData["age"].get<int>() << std::endl;
    }
    
    if (jsonData.contains("scores") && jsonData["scores"].is_object()) {
        for (auto& [key, value] : jsonData["scores"].items()) {
            if (value.is_number()) {
                std::cout << key << ": " << value.get<int>() << std::endl;
            }
        }
    }
    
    return 0;
}

4.2 RapidJSON

RapidJSON是一个高性能的C++ JSON解析器和生成器,适用于对速度有较高要求的应用场景。它基于SAX和DOM两种解析模式,提供灵活且高效的JSON处理能力。

更多信息和安装指南,请访问RapidJSON GitHub仓库。

4.3 cJSON

cJSON是一个轻量级的C JSON库,适用于嵌入式系统和资源受限的环境。虽然主要用于C语言,但也可以在C++项目中使用。

更多信息和安装指南,请访问cJSON GitHub仓库。

5. 比较与选择

不同的JSON库在功能、性能和易用性方面各有优劣。以下是对几种常用JSON库的简要比较:

库名称 优点 缺点
JsonCpp 成熟稳定,功能全面,支持复杂嵌套结构 接口相对繁琐,编译速度较慢
nlohmann/json 接口简洁,易于使用,支持现代C++特性 性能不如RapidJSON,依赖较多
RapidJSON 高性能,支持SAX和DOM解析模式,灵活性强 接口较为复杂,学习曲线陡峭
cJSON 轻量级,适用于嵌入式系统 功能较为基础,不支持C++特性

选择合适的JSON库应根据项目需求、开发团队的熟悉程度以及性能要求等因素综合考虑。

结论

在C++中解析特定结构的JSON并提取其中的数字部分,可以通过多种方法实现。对于结构复杂的JSON数据,推荐使用专门的JSON解析库如或,它们提供了强大的解析和数据操作能力。对于结构简单且对性能要求较高的场景,可以考虑使用std::regex或简单的字符串处理方法。然而,这些方法在处理复杂JSON结构时可能存在局限性。

综上所述,选择合适的工具和方法不仅能够提高开发效率,还能确保代码的可维护性和可靠性。希望本文能够为C++开发者在处理JSON数据时提供有价值的参考和指导。

参考资源


Last updated January 8, 2025

AI-assisted research. Sources, methodology and corrections · Source-checked guides and tools · Explore published answers

Ask Ithy AI