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

时间:2019-09-06 14:08:43

标签: 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;
}

我想检测该值超出预期范围。有可能以某种方式实现吗?

2 个答案:

答案 0 :(得分:8)

执行所需操作的唯一方法是实际检索更大的整数类型的值,然后检查该值是否在weakSelf.navigationItem.rightBarButtonItem的范围内。

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... } 期间使用parse()std::strtoull(取决于std::strtoll符号的存在)来解析该数字,并将其转换为{{1 }}(- 1 )或nlohmann::json::number_integer_tint64_t 1 )。

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

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

1 uint64_tint是默认类型,因为int64_t实际上是uint64_t模板的别名(很像nlohmann::json),但您可以使用所需的任何类型。

答案 1 :(得分:3)

除了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;
}

打印:

Long: false
Int: true

Try it online

请注意,这是一个警告:如果存储在JSON中的值是双精度或浮点型,并且以long或int形式检索,则它自然会得出true(12.3!= 12),但不会不必暗示溢出。您可以使用is_number_integer()(检查int,long和各种其他类型,未签名或有符号)和is_number_float()(检查double / float)检查常规类型。

据我所知,从int / long到double不会失败。但是,由于提供了足够大的数字the library will fail to parse the numberjson.exception.out_of_range.406),因此库存在硬限制。据我所知,该限制设置为1.79769e+308(至少在Wandbox上)或最大double值。这也使double成为您无法在库中溢出的唯一类型。

就以某种类型检索号码时自动检查号码是否溢出而言,不支持开箱即用。