I don't understand why this small program asserts. Both j
and jj
are fully parsed json objects that should be equivalent, but apparently they are not.
As far as I understood json j = json::parse(jsonstr)
and json j = jsonstr
should do the same thing.
If not, what does json jj = jsonstr
do?
#include <iostream>
#include <cassert>
#include "nlohmann/json.hpp"
using json = nlohmann::json;
std::string get_string(const json& j, const std::string& key, const std::string& default_val = "N/A")
{
return j.contains(key) && j[key].is_string() ? j[key].get<std::string>() : default_val;
}
int main() {
std::string jsonstr =
R"(
{
"error": {
"code": 401,
"message": "Request had invalid authentication credentials",
"errors": [
{
"message": "Invalid Credentials",
"domain": "global"
}
],
"status": "UNAUTHENTICATED"
},
"id" : "123"
}
)";
json j = json::parse(jsonstr); // j is now a fully parsed json object
auto id1 = get_string(j, "id", "");
assert(id1 == "123"); // this works as expected
json jj = jsonstr; // jj is now also a fully parsed json object equivalent to j
auto id2 = get_string(jj, "id", ""); // after this line "id2" contains "" instead of "123"
assert(id2 == "123"); // asserts here
}
As far as I understood
json j = json::parse(jsonstr)
andjson j = jsonstr
should do the same thing.
No, the former parses the string to return an object in you case, whereas the later returns an (unparsed) string.
You might print both j
and jj
to see the difference: Demo
j = {"error":{"code":401,"errors":[{"domain":"global","message":"Invalid Credentials"}],"message":"Request had invalid authentication credentials","status":"UNAUTHENTICATED"},"id":"123"}
jj = "\n{\n \"error\": {\n \"code\": 401,\n \"message\": \"Request had invalid authentication credentials\",\n \"errors\": [\n {\n \"message\": \"Invalid Credentials\",\n \"domain\": \"global\"\n }\n ],\n \"status\": \"UNAUTHENTICATED\"\n },\n \"id\" : \"123\"\n}\n"