使用“现代C ++的JSON”库检测到整数不适合指定的类型吗?

vkr*_*rzv 9 c++ json nlohmann-json

此代码打印-1

#include <iostream>
#include <nlohmann/json.hpp>

int main()
{
    auto jsonText = "{ \"val\" : 4294967295 }";
    auto json = nlohmann::json::parse(jsonText);
    std::cout << json.at("val").get<int>() << std::endl;
}
Run Code Online (Sandbox Code Playgroud)

我想检测出该值超出预期范围。是否有可能以某种方式完成?

Hol*_*olt 8

进行所需操作的唯一方法是实际检索较大的整数类型的值,然后检查该值是否在的范围内int

using integer_t = nlohmann::json::number_integer_t;
auto ivalue = json.at("val").get<integer_t>();

if (ivalue < std::numeric_limits<int>::min() || ivalue > std::numeric_limits<int>::max()) {
    // Range error... 
}
Run Code Online (Sandbox Code Playgroud)

一些细节...

该数字在调用parse() 使用std::strtoullstd::strtoll(取决于-符号的存在)期间进行解析,并转换为nlohmann::json::number_integer_tint64_t1)或nlohmann::json::number_unsigned_tuint64_t1)。

当您使用来查询值时get<int>,唯一要做的就是将存储的int64_t/ uint64_t值强制转换为int,因此此时无法检查范围。

另外,由于仅存储实际(无符号)整数值,因此无法检索原始的“字符串”。

1 int64_tuint64_t是默认类型,因为nlohmann::json它实际上是basic_json模板的别名(类似于std::string),但是您可以使用所需的任何类型。


Zoe*_*Zoe 5

除了 Holt 的回答,您还可以利用operator==库定义,其中指出:

整数和浮点数在比较前会自动转换。请注意,两个 NaN 值始终被视为不相等。

这里发生的是数字溢出,这意味着json["val"] != json["val"].get<int>(). 免责声明:我不知道这种方法与 Holt 的方法相比效率如何

#include <iostream>
#include <nlohmann/json.hpp>

int main()
{
    auto jsonText = "{ \"val\" : 4294967296 }";
    auto json = nlohmann::json::parse(jsonText);
    auto val = json["val"].get<long long>();
    auto i = json["val"].get<int>();
    bool longOverflow = json["val"] != val;
    bool intOverflow = json["val"] != i;
    std::cout << std::boolalpha << "Long: " << longOverflow << "\nInt: " << intOverflow;
}
Run Code Online (Sandbox Code Playgroud)

印刷:

Long: false
Int: true
Run Code Online (Sandbox Code Playgroud)

网上试试

请注意,这有一个警告:如果存储在 JSON 中的值是 double 或 float,并且作为 long 或 int 检索,它自然会评估为 true (12.3 != 12),但它没有暗示溢出。您可以使用is_number_integer()(检查 int、long 和各种其他类型,无符号或有符号)和is_number_float()(检查双精度/浮点数)来检查一般类型。

不过,据我所知,从 int/long 到 double 不会失败。但是,如果提供足够大的数字,库将无法解析数字( json.exception.out_of_range.406),因此库强加了硬性限制。据我所知,该限制设置为1.79769e+308(至少在 Wandbox 上)或最大双精度值。这也使 double 成为您不能溢出库的唯一类型。

至于在使用某种类型检索时自动检查数字溢出,这是不支持的。