access array using 'nlohmann' JSON parser - c++

I am trying to access an JSON array using 'nlohmann' library, as the example below shows:
#include <iostream>
#include <string>
#include "json.hpp"
using json = nlohmann::json;
int main() {
{
const std::string str(
R"(
{
"result":{
"lines":[
{
"i":1,
"w":7,
},
{
"i":1,
"w":8,
}
]
},
"success":true
}
)");
json root(str);
auto result = root.find("result");
if (result != root.end()) {
std::cout << *result << std::endl;
} else {
std::cout << "'result' not found\n";
}
}
}
Can anyone help and explain why the output is 'result' not found? According to the examples I read in https://github.com/nlohmann/json and other references I found, it should work.

I found the error.
I should be json root(json::parse(str)); and not json root(str);

Related

Boost::JSON, parsing string

So this is my JSON:
string js = R"({"table":"orderBookL2_25","action":"insert","data":[{"symbol":"XBTUSD","id":8796514950,"side":"Buy","size":10000,"price":34850.5},{"symbol":"XBTUSD","id":8796515700,"side":"Buy","size":281,"price":34843}]})";
I want to somehow convert it into object that could help me to conveniently access values. For example, something like that;
parsed_data["data"][0]["symbol"]
I have tried to use JSON::Boost but I don't know how to parse using this library. I have tried this code:
json::value parsed_data{js}; cout << parsed_data.at(0);
But the output from it is worthless:
"{\"table\":\"orderBookL2_25\",\"action\":\"insert\",\"data\":[{\"symbol\":\"XBTUSD\",\"id\":8796514950,\"side\":\"Buy\",\"size\":10000,\"price\":34850.5},{\"symbol\":\"XBTUSD\",\"id\":8796515700,\"side\":\"Buy\",\"size\":281,\"price\":34843}]}"
Basically your code (which you showed in fuzzy way) assigned string to JSon value object, that is why some signs has been escaped.
Problem is that you do not read documentation.
Please read JSon quick look note section how to parse input:
Quick Look - 1.75.0
Parsing
JSON can be parsed into the value container in one step using a free function. In the following snippet, a parse error is indicated by a thrown exception:
value jv = parse( "[1, 2, 3]" );
Error codes are also possible:
error_code ec;
value jv = parse( R"( "Hello, world!" )", ec );
Then fix code for example like this:
#include <iostream>
#include <vector>
#define BOOST_JSON_STACK_BUFFER_SIZE 1024
#include <boost/json/src.hpp>
#include <boost/json.hpp>
using namespace boost::json;
int main()
{
std::string js = R"({
"table":"orderBookL2_25",
"action":"insert",
"data":[
{
"symbol":"XBTUSD",
"id":8796514950,
"side":"Buy",
"size":10000,
"price":34850.5
},
{
"symbol":"XBTUSD",
"id":8796515700,
"side":"Buy",
"size":281,
"price":34843
}
]
})";
try {
auto parsed_data = parse(js);
std::cout << value_to<std::string>(parsed_data.at("data").at(0).at("symbol")) << '\n';
}
catch(const std::exception& e)
{
std::cerr << e.what() << '\n';
}
return 0;
}
Live demo

C++ How to parse JSON response using cppRest Library?

I am trying to parse JSON response using cppRest Library, but an exception is raised instead the JSON object, here is the error that is show below:
Incorrect Content-Type: must be textual to extract_string, JSON to extract_json.
And here is my code that I have tried so far:
#include <iostream>
#include <cpprest/http_client.h>
using namespace web::http;
using namespace web::http::client;
using namespace web;
using namespace std;
int main()
{
uri url(L"http://www.7timer.info/bin/astro.php?lon=113.2&lat=23.1&ac=0&unit=metric&output=json&tzshift=0");
http_client client(url);
http_response response;
http_request req;
req.set_method(methods::GET);
req.headers().set_content_type(L"application/json");
response = client.request(req).get();
try
{
json::object json_object(response.extract_json().get().as_object());
}
catch (exception &e)
{
cout << e.what() << "\n";
}
return 0;
}
I solved my problem, looks like I need to set the response headers to get the received content type as json:
Updated my code:
#include <iostream>
#include <cpprest/http_client.h>
using namespace web::http;
using namespace web::http::client;
using namespace web;
using namespace std;
int main()
{
uri url(L"http://www.7timer.info/bin/astro.php?lon=113.2&lat=23.1&ac=0&unit=metric&output=json&tzshift=0");
http_client client(url);
http_request req;
req.set_method(methods::GET);
pplx::task<json::value> requestTask = client.request(req).then([](http_response response)
{
json::value jsonObject;
try
{
if ( response.status_code() == status_codes::OK )
{
response.headers().set_content_type(L"application/json"); // Set headers to receive content type as JSON
jsonObject = response.extract_json().get();
}
}
catch (const http_exception& e)
{
cout << e.error_code().message() << "\n";
}
return jsonObject; // returned a json value
});
json::array dataseries = requestTask.get().at(L"dataseries").as_array(); // We get the returned response here
for (size_t i = 0; i < dataseries.size(); i++)
{
auto timepoint = dataseries[i].at(L"timepoint");
wcout << timepoint << endl;
}
return 0;
}

Add values to map using rapidjson

I get a raw json string
{"vehicle": {"brand": "zonda","color": "blue"},"username": {"brand": "doyota","color": "red"}}
from a get call i make.
I read that rapidjson is the best way to parse a json string in cpp.
So I tried doing something like this:
const char* json = data.c_str();
rapidjson::Document document;
if (document.Parse(json).HasParseError()) {
cout << "has parse error" << endl;
return 1;
}
else {
assert(document.IsObject());
}
Here it says that the json has a parse error. Any idea why this could be?
Also once I am able to parse the values I want to add them as key value pairs to a standard map. Could anyone point me in the right direction to proceed with this?
This gave me no error:
#include <iostream>
#include "rapidjson/document.h"
#include "rapidjson/error/en.h"
using namespace rapidjson;
int main() {
Document d;
std::string json = R"raw({"vehicle": {"brand": "zonda","color": "blue"},"username": {"brand": "doyota","color": "red"}})raw";
if (d.Parse(json.c_str()).HasParseError()) {
std::cout << "has error\n";
} else {
std::cout << "no error\n";
}
}
Tried C++11 - C++20 and it all seems fine. My guess is that you've got some non UTF8 character in the data.

How to read JSON content as it is in C++?

I am trying read a text file which has Valid JSON content but not string. The below code works fine if it is a string dump. For example - if file contents are like this "{ \"happy\": true, \"pi\": 3.141 }" then it will parse without errors. Now I want to find out a way which minimizes these conversion ? How to convert JSON content to String dump in C++ using any standard lib? I am using nlohmann for now, but seems like this requires additional coding. Please educate me if I can hack this with simple code.
My Code
#include <iostream>
#include <fstream>
#include <streambuf>
#include <nlohmann/json.hpp>
using namespace std;
using json = nlohmann::json;
int main()
{
std::fstream f_json("C://json.txt");
json jFile;
try {
jFile = json::parse(f_json);
}
catch (json::parse_error &e)
{
std::cerr << e.what() << std::endl;
}
return 0;
}
Our client produces JSON files which is like below.
{
"happy": true,
"pi": 3.141
}
My file is under C:/test.json, so it dint had the permission to open it. Now I placed it in proper folder. Now its working fine.
I like to use ThorsSerializer. Disclaimer I wrote it.
#include "ThorSerialize/JsonThor.h"
#include "ThorSerialize/SerUtil.h"
#include <sstream>
#include <iostream>
#include <string>
struct MyObj
{
bool happy;
double pi;
};
ThorsAnvil_MakeTrait(MyObj, happy, pi);
Example Usage:
int main()
{
using ThorsAnvil::Serialize::jsonImport;
using ThorsAnvil::Serialize::jsonExport;
std::stringstream file(R"({ "happy": true, "pi": 3.141 })");
MyObj data;
file >> jsonImport(data);
std::cout << jsonExport(data) << "\n";
}
Output:
{
"happy": true,
"pi": 3.141
}
It works the same for a file stream. But you should not escape the " characters in the file.

How to decode an std::string formated JSON into a Boost Property tree?

Suppose that I'm receiving a JSON formated string from network and want to decode it in a Boost Property tree. What the best way of doing that?
For creating a easy example, lets assume we have a string in the code to represent the string that you are going to receive from the network with the following content:
{
"Test": "string",
"Test2":
{
"inner0": "string2",
"inner1": "string3",
"inner2": "1234"
}
}
So the code for interpreting that as a string is the following:
#include <boost/property_tree/json_parser.hpp>
#include <iostream>
#include <sstream>
int main()
{
std::stringstream buffer("{ \"Test\": \"string\", \"Test2\": { \"inner0\": \"string2\", \"inner1\": \"string3\", \"inner2\": \"1234\" } }");
std::cout << buffer.str() << std::endl;
boost::property_tree::ptree pt;
boost::property_tree::json_parser::read_json(buffer, pt);
std::string test2_inner0_str = pt.get<std::string>("Test2.inner0");
int test2_inner2_value = pt.get<int>("Test2.inner2");
std::cout << test2_inner0_str << std::endl;
std::cout << test2_inner2_value << std::endl;
}
Prints:
Live On Coliru
{ "Test": "string", "Test2": { "inner0": "string2", "inner1": "string3", "inner2": "1234" } }
string2
1234