1 nlohman json序列化输出字符串

1.1 存在的问题

nlohman json的json对象中有浮点数时,序列化之后的json字符串中浮点数过长,比如

#include <iostream>

#include "nlohmann/json.hpp"

int main() {
    nlohmann::json root;
    root["value1"] = 0.9445641561631231;
    root["value2"] = 0.14654564561;
    root["value3"] = 0.154565465;
    root["value4"] = 7416546513.014654156;

    std::cout << root.dump() << std::endl;

    return 0;
}

上述代码输出

{
    "value1": 0.9445641561631231,
    "value2": 0.14654564561,
    "value3": 0.154565465,
    "value4": 7416546513.014654
}

在有些时候我们可能不需要这么精确地浮点数表示,只需要小数点后几位就行,当数据量比较多的时候,只保留浮点数小数点后几位更加有利于减少json字符串大小,节省带宽。

1.2 nlohman json序列化输出字符串只保留浮点数小数点后几位

我们可以通过一个后处理方法,将json对象中的浮点数做小数点减少,具体的实现代码如下

#include <iostream>
#include <sstream>

#include "nlohmann/json.hpp"

inline void serialize_with_precision(nlohmann::json& j, int precision = 3) {
    if (j.is_number_float()) {
        std::ostringstream oss;
        oss << std::fixed << std::setprecision(precision) << j.get<double>();
        j = oss.str(); // 将浮点数替换为格式化后的字符串  
    }
    else if (j.is_object()) {
        for (auto& it : j.items()) {
            serialize_with_precision(it.value(), precision);
        }
    }
    else if (j.is_array()) {
        for (auto& elem : j) {
            serialize_with_precision(elem, precision);
        }
    }
    // 对于其他类型(如整数、布尔值、字符串等),不做处理  
}

int main() {
    nlohmann::json root;
    root["value1"] = 0.9445641561631231;
    root["value2"] = 0.14654564561;
    root["value3"] = 0.154565465;
    root["value4"] = 7416546513.014654156;

    serialize_with_precision(root, 3);

    std::cout << root.dump() << std::endl;

    return 0;
}

输出结果如下

{
    "value1": "0.945",
    "value2": "0.147",
    "value3": "0.155",
    "value4": "7416546513.015"
}

我们通过一个递归操作对json对象中的所有float对象进行了格式转换,不过这里有个问题是序列化之后数值变成了字符串,不过这可以在json解析操作中进行处理。