我正在使用nlohmann的json C ++实现进行项目开发。
如何在GDB中轻松浏览nlohmann的JSON键/值?
我尝试使用此STL gdb包装,因为它提供了帮助者探索nlohmann的JSON库正在使用的标准C ++库结构。但是我觉得不方便。
这是一个简单的用例:
json foo;
foo["flex"] = 0.2;
foo["awesome_str"] = "bleh";
foo["nested"] = {{"bar", "barz"}};
Run Code Online (Sandbox Code Playgroud)
我想在GDB中拥有什么:
(gdb) p foo
{
"flex" : 0.2,
"awesome_str": "bleh",
"nested": etc.
}
Run Code Online (Sandbox Code Playgroud)
当前行为
(gdb) p foo
$1 = {
m_type = nlohmann::detail::value_t::object,
m_value = {
object = 0x129ccdd0,
array = 0x129ccdd0,
string = 0x129ccdd0,
boolean = 208,
number_integer = 312266192,
number_unsigned = 312266192,
number_float = 1.5427999782486669e-315
}
}
(gdb) p foo.at("flex")
Cannot evaluate …
Run Code Online (Sandbox Code Playgroud) 我正在使用nlohmann的json库来处理c ++中的json对象.最后,我想从文件中读取一个json对象,例如像这样的简单对象.
{
"happy": true,
"pi": 3.141
}
Run Code Online (Sandbox Code Playgroud)
我不太清楚如何处理这个问题.在https://github.com/nlohmann上,有几种方法可以从字符串文字中反序列化,但是将它扩展为读入文件似乎并不容易.有任何人对此有经验吗?
我有一个字符串,我想将其解析为 json,但_json
似乎每次都不起作用。
#include <nlohmann/json.hpp>
#include <iostream>
using nlohmann::json;
int main()
{
// Works as expected
json first = "[\"nlohmann\", \"json\"]"_json;
// Doesn't work
std::string s = "[\"nlohmann\", \"json\"]"_json;
json second = s;
}
Run Code Online (Sandbox Code Playgroud)
第一部分有效,第二部分抛出terminate called after throwing an instance of 'nlohmann::detail::type_error'
what(): [json.exception.type_error.302] type must be string, but is array
。
我有以下 json 数据:
{
"images": [
{
"candidates": [
{
"confidence": 0.80836,
"enrollment_timestamp": "20190613123728",
"face_id": "871b7d6e8bb6439a827",
"subject_id": "1"
}
],
"transaction": {
"confidence": 0.80836,
"enrollment_timestamp": "20190613123728",
"eyeDistance": 111,
"face_id": "871b7d6e8bb6439a827",
"gallery_name": "development",
"height": 325,
"pitch": 8,
"quality": -4,
"roll": 3,
"status": "success",
"subject_id": "1",
"topLeftX": 21,
"topLeftY": 36,
"width": 263,
"yaw": -34
}
}
]
}
Run Code Online (Sandbox Code Playgroud)
我需要检查subject_id
上面的json数据中是否存在。为此,我在下面做了:
auto subjectIdIter = response.find("subject_id");
if (subjectIdIter != response.end())
{
cout << "it is found" << endl;
}
else
{
cout << …
Run Code Online (Sandbox Code Playgroud) 我有一个简单的项目,需要三个只有头的库才能编译:websocketpp,spdlog和nlohmann/json.
项目结构如下所示:
??? src
??? app
? ??? CMakeLists.txt
? ??? src
? ??? test
??? CMakeLists.txt
??? core
? ??? CMakeLists.txt
? ??? include
? ??? src
? ??? test
??? vendor
??? install.cmake
??? nlohmann_json
??? spdlog
??? websocketpp
Run Code Online (Sandbox Code Playgroud)
根CMakeLists.txt如下:
cmake_minimum_required(VERSION 3.6.1 FATAL_ERROR)
..
# External 3rd party libs that we include
include(vendor/install.cmake)
add_subdirectory(core)
add_subdirectory(app)
Run Code Online (Sandbox Code Playgroud)
这个想法基本上是每个子目录都是一个库(例如core
),并app
"聚合"所有子目录.每个库(例如core
)都是这样构建的(core/CMakeLists.txt
):
project(foo-core VERSION 0.1 LANGUAGES CXX)
add_library(foo-core
src/foobar/foobar.cc
src/foobaz/baz.cc) …
Run Code Online (Sandbox Code Playgroud) 此代码打印-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)
我想检测出该值超出预期范围。是否有可能以某种方式完成?
我在嵌入式项目中使用nlohmann json(现代 C++ 的 JSON) 。操作系统是Mongoose操作系统。Mongoose 有一个很好的配置系统,其中配置数据被处理并布置在 mos.yml 文件中。该文件在构建时被转换为结构和访问器函数。因此,我可以将配置数据作为结构获取,其中包含其他嵌套结构。我需要将其转换为 JSON。
我的理解是 nlohmann::json 能够将 JSON 与我自己的类型相互转换,我所要做的就是提供to_json()
和from_json()
方法,如下所述:
这个示例代码非常简单:
struct person {
std::string name;
std::string address;
int age;
};
void to_json(json& j, const person& p) {
j = json{{"name", p.name}, {"address", p.address}, {"age", p.age}};
}
Run Code Online (Sandbox Code Playgroud)
但给出的例子非常简单。我的类型更复杂,我无法弄清楚更复杂结构的语法,例如这个(为简洁起见摘录):
struct mgos_config_mytype {
struct mgos_config_mytype_input input;
struct mgos_config_mytype_speed speed;
/* many others omitted */
};
struct mgos_config_mytype_input {
struct mgos_config_mytype_input_wired_buttons wired_buttons;
};
struct mgos_config_mytype_input_wired_buttons {
const char * …
Run Code Online (Sandbox Code Playgroud) 这是我的代码和错误,下面我将展示一些有效的代码。
\n#include <iostream>\n#include <string>\n\n#include <nlohmann/json.hpp>\n\nusing JSON = nlohmann::json;\nusing std::cout;\nusing std::endl;\nusing std::string;\n\ntemplate <class ObjectType>\nvoid dump(const JSON &json) {\n for (auto &[key, value]: json.items()) {\n string foo = value.get<std::string>();\n cout << "Key: " << key;\n cout << " Value: " << foo << endl;\n }\n}\n\nint main(int, char **) {\n JSON json;\n json["alpha"] = "beta";\n dump<string>(json);\n} \n
Run Code Online (Sandbox Code Playgroud)\n-$ g++ -std=c++17 Foo.cpp -o Foo && Foo\nFoo.cpp: In function \xe2\x80\x98void dump(const JSON&)\xe2\x80\x99:\nFoo.cpp:14:37: error: expected primary-expression before \xe2\x80\x98>\xe2\x80\x99 token\n 14 | string foo = …
Run Code Online (Sandbox Code Playgroud) 在导入到我的 C++ 程序中的 json 文件中,结构如下:
{
"a":"1",
"ec":[
{
"a":"0x00",
"s":[
{"a":"0xA0"},
{"a":"0xA1"},
],
"b":"v1"
},
{
"a":"0x01",
"s":[
{"a":"0xB0"},
{"a":"0xB1"},
],
"b":"v2"
}
]
}
Run Code Online (Sandbox Code Playgroud)
我想迭代"ec"
数组并获取所有数组的值,"a"
并且每个数组"a"
的值都相同s
vector<string> ec_a; // should contain {"0x00","0x01"}
vector<string> a1_s; // should contain {"0xA0", "0xA1"}
vector<string> a2_s; // should contain {"0xB0","0xB1"}
Run Code Online (Sandbox Code Playgroud)
首先我得到了大小,ec
但从我理解的文档中应该使用迭代器来完成其余的工作
int n=j["ec"].size() // n = 2
for(auto it=j["ec"].begin();it!=j["ec"].end();++it){
if(it.key() == "a") ec_a.push_back(it.value());
}
Run Code Online (Sandbox Code Playgroud)
但得到这个例外nlohmann::detail::invalid_iterator at memory location
我认为这j["ec"].begin()
是不正确的。
我该怎么做,谢谢。
我using V = std::variant<A, B, C>
的原型有一些变体和功能V parse(const json&)
。函数应尝试解析所有类型(例如A
,,B
然后C
),直到首次成功为止(并且应隐式执行,因为及时会有很多类型)。
如何实现这种东西?
我们可能会std::variant_size
以某种方式使用。
这是我需要的东西。
我的解决方案是显式列出所有类型的解析器。
V parse(const json& i_j)
{
using Parser = std::function<MaybeV(const json&)>;
static const auto ps = std::vector<Parser>{
[](const auto& j)->MaybeV{return j.get<std::optional<A>>;},
[](const auto& j)->MaybeV{return j.get<std::optional<B>>;},
[](const auto& j)->MaybeV{return j.get<std::optional<C>>;}
};
for (const auto& p : ps)
if (auto opt_result = p(i_j))
return std::move(*opt_result);
throw ParseError("Can't parse");
}
Run Code Online (Sandbox Code Playgroud)
但是,它肯定可以简化,因为lambda的类型仅不同,而我真正需要的是迭代的类型std::variant
。