为什么我不能使用 [] 运算符访问 nlohmann 的 C++ JSON 库中的数组?
Why can't I use the [] operator to access an array in nlohmann's C++ JSON library?
我正在使用 C++ 的 this JSON 库,以便从 Twitter 的 API 获取信息,其中 returns 一个 JSON 数组到我的程序(我存储在 responseData 中)。但是当我尝试访问返回数组中的 "name" 时,它不允许我这样做。
这是我在进程终止后遇到的错误:
terminate called after throwing an instance of 'nlohmann::detail::type_error'
what(): [json.exception.type_error.305] cannot use operator[] with array
这是我正在处理的代码部分:
if(!responseData.empty()&&response_code==0) {
std::cout<<responseData<<"<---\n";
std::cout<<nlohmann::json::parse(responseData.c_str())["name"]<<"<!-\n";
}
我对JSON知之甚少,这是我第一次接触上述库,但我觉得这个问题很有趣,代码对我来说是一个挑战,所以我将尝试解释我的发现。
发生的情况是,您使用 operator[]()
通过键访问 basic_json<>
对象,而不是索引,该对象应该是内部类型 value_t::object
(enum class value_t {}
).如果该条件失败,则会抛出您看到的异常,并报告对象的实际类型。据我所知,对象的类型由解析器根据您传递给它的字符串的语法自动确定。 (好吧,它可以不仅仅是一个字符串,据我所知,还有一个可以表示线性字符范围的各种实体的重载列表。)以 a 开头的数据报告 "Array"方括号 "["
.
因此,为了确定发生了什么,我们需要查看解析器正在接收的实际数据。正如我在上面提到的,似乎有一个类型的自动推导,并且每种类型只允许一定范围的操作。要使用键值访问器,字符串看起来应该表示一个对象,并以大括号 "{"
.
开头
给定示例数据:
[
{
"trends":
[
{
"name":"#XboxE3",
"url":"http:\/\/twitter.com\/search?q=%23XboxE3",
"promoted_content":null,
"query":"%23XboxE3",
"tweet_volume":371447
},
{
"name":"Anthem",
"url":"http:\/\/twitter.com\/search?q=Anthem",
"promoted_content":null,
"query":"Anthem",
"tweet_volume":71013
}
],
"as_of":"2017-06-11T22:57:57Z",
"created_at":"2017-06-11T22:55:37Z",
"locations":
[
{
"name":"Worldwide",
"woeid":1
}
]
}
]
这似乎是一个分层数据结构,因此要到达 "name"
元素,您需要向其下降。最顶层的元素是由 []
表示的数组。它包含一个元素——一个未命名的对象。我们需要 "trends"
数组。在那个数组中,每个元素都是一个对象。所以我认为查询看起来像这样:
auto response = nlohmann::json::parse(responseData.c_str());
std::cout << response[0]["trends"][0]["name"];
operator[]()
应该是可链接的,因为它们 return 是对 basic_json<>
对象的引用。这就是运算符链接的实现方式,链接本身就是一个典型的设计。在 std::cin
的 operator<<()
中使用了相同的想法。
我正在使用 C++ 的 this JSON 库,以便从 Twitter 的 API 获取信息,其中 returns 一个 JSON 数组到我的程序(我存储在 responseData 中)。但是当我尝试访问返回数组中的 "name" 时,它不允许我这样做。
这是我在进程终止后遇到的错误:
terminate called after throwing an instance of 'nlohmann::detail::type_error' what(): [json.exception.type_error.305] cannot use operator[] with array
这是我正在处理的代码部分:
if(!responseData.empty()&&response_code==0) {
std::cout<<responseData<<"<---\n";
std::cout<<nlohmann::json::parse(responseData.c_str())["name"]<<"<!-\n";
}
我对JSON知之甚少,这是我第一次接触上述库,但我觉得这个问题很有趣,代码对我来说是一个挑战,所以我将尝试解释我的发现。
发生的情况是,您使用 operator[]()
通过键访问 basic_json<>
对象,而不是索引,该对象应该是内部类型 value_t::object
(enum class value_t {}
).如果该条件失败,则会抛出您看到的异常,并报告对象的实际类型。据我所知,对象的类型由解析器根据您传递给它的字符串的语法自动确定。 (好吧,它可以不仅仅是一个字符串,据我所知,还有一个可以表示线性字符范围的各种实体的重载列表。)以 a 开头的数据报告 "Array"方括号 "["
.
因此,为了确定发生了什么,我们需要查看解析器正在接收的实际数据。正如我在上面提到的,似乎有一个类型的自动推导,并且每种类型只允许一定范围的操作。要使用键值访问器,字符串看起来应该表示一个对象,并以大括号 "{"
.
给定示例数据:
[
{
"trends":
[
{
"name":"#XboxE3",
"url":"http:\/\/twitter.com\/search?q=%23XboxE3",
"promoted_content":null,
"query":"%23XboxE3",
"tweet_volume":371447
},
{
"name":"Anthem",
"url":"http:\/\/twitter.com\/search?q=Anthem",
"promoted_content":null,
"query":"Anthem",
"tweet_volume":71013
}
],
"as_of":"2017-06-11T22:57:57Z",
"created_at":"2017-06-11T22:55:37Z",
"locations":
[
{
"name":"Worldwide",
"woeid":1
}
]
}
]
这似乎是一个分层数据结构,因此要到达 "name"
元素,您需要向其下降。最顶层的元素是由 []
表示的数组。它包含一个元素——一个未命名的对象。我们需要 "trends"
数组。在那个数组中,每个元素都是一个对象。所以我认为查询看起来像这样:
auto response = nlohmann::json::parse(responseData.c_str());
std::cout << response[0]["trends"][0]["name"];
operator[]()
应该是可链接的,因为它们 return 是对 basic_json<>
对象的引用。这就是运算符链接的实现方式,链接本身就是一个典型的设计。在 std::cin
的 operator<<()
中使用了相同的想法。