使用"JSON for Modern C++"库检测整数不适合指定类型?
Detect with "JSON for Modern C++" library that integer doesn't fit into a specified type?
此代码打印-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;
}
我想检测该值是否超出预期范围。是否有可能以某种方式完成?
执行所需操作的唯一方法是实际检索较大整数类型的值,然后检查该值是否在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
(取决于是否存在-
符号(解析该号码,并将其转换为nlohmann::json::number_integer_t
(int64_t
1( 或nlohmann::json::number_unsigned_t
(uint64_t
1(。
当你用get<int>
查询值时,唯一要做的就是从存储的int64_t
/uint64_t
值转换为int
,所以此时没有办法检查范围。
此外,您无法检索原始"字符串",因为仅存储实际(无符号(整数值。
1int64_t
和uint64_t
是默认类型,因为nlohmann::json
实际上是basic_json
模板的别名(很像std::string
(,但您可以使用所需的任何类型。
除了 Holt 的回答之外,您还可以利用库定义的operator==
,其中指出:
整数和浮点数在比较之前会自动转换。请注意,两个 NaN 值始终被视为不相等。
这里发生的事情是数字溢出,这意味着json["val"] != json["val"].get<int>()
.免责声明:我不知道这种方法与霍尔特的方法相比有多有效
#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
在线试用
请注意,这有一个警告:如果存储在 JSON 中的值是双精度值或浮点数,并且作为 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 成为您不能用库溢出的唯一类型。
至于在使用某种类型检索号码时自动检查号码溢出,这是开箱即用
的。- C++ 雷神库 - 使用资源加载器类时出现问题(不命名类型)
- 类中的字符串不命名类型
- 不完整类型错误(E0409、E0070、E0515)
- CRTP 单一实例不完整类型或非文本类型
- 使用具有结构不完整类型错误的模板
- 哪些存储了不完整类型的 STL 数据结构可以用作类成员?
- Xalloc 不命名类型
- (结构名/类名)不命名类型C++
- 是否允许类类型的 std::function 成员变量(不完整类型)?
- MSVC 在不知道类型的情况下评估上下文(和错误)
- 为什么我得到变量"Node"不是类型名称错误
- Visual Studio Code "variable " u8 的 C/C++ 扩展名 " " 不是类型名称"
- 将"std::string {aka std::basic_string}"赋值中的不兼容类型<char>
- 实例化具有不完整类型的类模板格式不正确(如果该类型是在之后定义的)
- C++ 外部类不命名类型
- C++ 类型类的变量声明不命名类型?
- 如何在不违反类型别名规则的情况下解释消息负载?
- msgpack:在不知道类型的情况下解包自定义类
- 不允许将SDL_Cursor与unique_ptr:error不完整类型一起使用
- 使用"JSON for Modern C++"库检测整数不适合指定类型?