Reading Array of the json in JsonCpp - c++

I tried to write a simple JSON reader for my program then I use JsonCpp. I have this JSON from my web server:
{
"return":
{
"status":200,
"message":"Accepted"
},
"entries":
[
{
"messageid":185002992,
"message":"CplusItsGood",
"status":1,
"statustext":"test",
"sender":"1234567",
"receptor":"123456789",
"date":1234,
"cost":140
}
]
}
And this is my C++ code:
Json::Reader reader;
Json::Value root;
reader.parse(jsonContext, root, false);
const Json::Value entriesArray = root["return"]["entries"];
int A = entriesArray["sender"].asInt();
cout << A;
It's print only 0, I can't read the sender or any other element of the entries array.
I want get the value of the cost or sender for example.
How can I do that?

your root contains 2 elements "return" and "entries" so or
root["return"] or root["entries"]
Then - array contains a list of members - so even if it only one entry - you still have to get it.
if value is quoted - it is string - you cannot use getInt on it. For example getInt is applicable to "status" not "sender"
Here is the whole sample
#include <iostream>
#include <string>
#include <json/json.h>
int main()
{
std::string s = R"({
"return":
{
"status":200,
"message":"Accepted"
},
"entries":
[
{
"messageid":185002992,
"message":"CplusItsGood",
"status":1,
"statustext":"test",
"sender":"1234567",
"receptor":"123456789",
"date":1234,
"cost":140
}
]
})";
Json::Reader reader;
Json::Value root;
reader.parse(s, root, false);
auto entriesArray = root["entries"];
auto firstelem = entriesArray[0];
std::string sender = firstelem["sender"].asString();
int i = std::stoi(sender);
std::cout << "array:" << entriesArray << "\n";
std::cout << "element:" << firstelem << "\n";
std::cout << "value:" << sender << "\n";
std::cout << "parsed value:" << i << "\n";
}
Output
array:[
{
"cost" : 140,
"date" : 1234,
"message" : "CplusItsGood",
"messageid" : 185002992,
"receptor" : "123456789",
"sender" : "1234567",
"status" : 1,
"statustext" : "test"
}
]
element:{
"cost" : 140,
"date" : 1234,
"message" : "CplusItsGood",
"messageid" : 185002992,
"receptor" : "123456789",
"sender" : "1234567",
"status" : 1,
"statustext" : "test"
}
value:1234567
parsed value:1234567

For arrays with only 1 object, use 0.
const Json::Value entriesArray = root["entries"][0];

Related

access json array values in c++

I'm new to c++ and trying to use nlohmann library and I'm quite stuck. I want to modify array of objects from json.
json =
{
"a": "xxxx",
"b": [{
"c": "aaa",
"d": [{
"e": "yyy"
},
{
"e": "sss",
"f": "fff"
}
]
}]
}
now I want to replace e value with "example" in the above structure. Could some one help me.
I tried to loop through the json structure and was able to read the "e" value but can't replace it. I tried: `
std::vector<std::string> arr_value;
std::ifstream in("test.json");
json file = json::parse(in);
for (auto& td : file["b"])
for (auto& prop : td["d"])
arr_value.push_back(prop["e"]);
//std::cout<<"prop" <<prop["e"]<< std::endl;
for (const auto& x : arr_value)
std::cout <<"value in vector string= " <<x<< "\n";
for (decltype(arr_value.size()) i = 0; i <= arr_value.size() - 1; i++)
{
std::string s = arr_value[i]+ "emp";
std::cout <<"changed value= " <<s << std::endl;
json js ;
js = file;
std::ofstream out("test.json");
js["e"]= s;
out << std::setw(4) << js << std::endl;
}
The following appends MODIFIED to every "e"-value and writes the result to test_out.json:
#include <vector>
#include <iostream>
#include <fstream>
#include <nlohmann/json.hpp>
using json = nlohmann::json;
int main() {
std::ifstream in("test.json");
json file = json::parse(in);
for (auto& td : file["b"])
for (auto& prop : td["d"]) {
prop["e"] = prop["e"].get<std::string>() + std::string(" MODIFIED");
}
std::ofstream out("test_out.json");
out << std::setw(4) << file << std::endl;
}
The prop["e"] = ... line does three things:
It gets the property with key "e",
Coerces it into a string using .get<std::string>() and appends "modified", and
writes back the result to prop["e"], which is a reference to the object nested in the JSON structure.

C++ nlohmann JSON get name of array

I have nlohmann json object:
json uuid = R"(
{
"uuid": ["aaa","bbb","ccc"]
}
)"_json;
I can get the values in array without problems: str = uuid["uuid"][0];
But how can i get array name himself ?
You can get the underlying map from the json object which gives you the array names and the arrays. If you just want to iterate through the items that's easy as well.
#include <iostream>
#include <json.hpp>
using json = nlohmann::json;
int main()
{
json uuid = R"(
{
"uuid": ["aaa","bbb","ccc"],
"uuie": ["aaa","bbb","ccc"],
"uuif": ["aaa","bbb","ccc"]
}
)"_json;
if (uuid.is_object())
{
auto obj = uuid.get<json::object_t>();
for (auto& kvp : obj)
{
std::cout << kvp.first << ":" << kvp.second << "\n";
}
}
for (auto& item : uuid)
{
std::cout << item << "\n";
}
return 0;
}

C++ JsonCpp: Loop through objects and get value

I got a little problem.
My json looks like this:
{
"data" :
{
"Money" :
{
"testUser3" : "500",
"testUser2" : "23",
"testUser1" : "2435",
"testUser" : "60"
}
}}
And I am trying to get the value + names of all the users.. but I don't know how, because the user names can change I can't use root["data"]["Money"]["testUser"].asInt();
I hope someone can help me, thanks.
you were downvoted, but I'll help you anyway, cause I need something similar.. let's thank Brandon in JsonCpp - when having a json::Value object, how can i know it's key name? for the keys part..
#include <string>
#include <iostream>
#include "jsoncpp-master/include/json/value.h"
#include "jsoncpp-master/include/json/json.h"
using namespace std;
bool Testjson2()
{
string s =
" { \"data\" :{"
" \"Money\" : {"
" \"testUser3\" : \"500\","
" \"testUser2\" : \"23\","
" \"testUser1\" : \"2435\","
" \"testUser\" : \"60\""
" }"
" } }";
Json::Value root;
Json::Reader reader;
string sdress = "{\"\":[" + s + "]}";
if (!reader.parse(sdress, root))
{
cout << sdress << "\n" << "Parse error\n";
return false;
}
const Json::Value datasections = root[""];
Json::Value v = datasections [0]["data"]["Money"];
cout << "There are " << v.size() << " members\n";
for (auto const& id : v.getMemberNames())
cout << id << " has " << v[id] << std::endl;
return true;
}

Parse JSON array as std::string with Boost ptree

I have this code that I need to parse/or get the JSON array as std::string to be used in the app.
std::string ss = "{ \"id\" : \"123\", \"number\" : \"456\", \"stuff\" : [{ \"name\" : \"test\" }] }";
ptree pt2;
std::istringstream is(ss);
read_json(is, pt2);
std::string id = pt2.get<std::string>("id");
std::string num= pt2.get<std::string>("number");
std::string stuff = pt2.get<std::string>("stuff");
What is needed is the "stuff" to be retrieved like this as std::string [{ "name" : "test" }]
However the code above stuff is just returning empty string. What could be wrong
Arrays are represented as child nodes with many "" keys:
docs
JSON arrays are mapped to nodes. Each element is a child node with an empty name. If a node has both named and unnamed child nodes, it cannot be mapped to a JSON representation.
Live On Coliru
#include <boost/property_tree/ptree.hpp>
#include <boost/property_tree/json_parser.hpp>
using boost::property_tree::ptree;
int main() {
std::string ss = "{ \"id\" : \"123\", \"number\" : \"456\", \"stuff\" : [{ \"name\" : \"test\" }, { \"name\" : \"some\" }, { \"name\" : \"stuffs\" }] }";
ptree pt;
std::istringstream is(ss);
read_json(is, pt);
std::cout << "id: " << pt.get<std::string>("id") << "\n";
std::cout << "number: " << pt.get<std::string>("number") << "\n";
for (auto& e : pt.get_child("stuff")) {
std::cout << "stuff name: " << e.second.get<std::string>("name") << "\n";
}
}
Prints
id: 123
number: 456
stuff name: test
stuff name: some
stuff name: stuffs
Since "stuff" is an array, you can iterate over the elements of it, which are dictionaries. And then you can iterate over the elements of the dictionary, which are key-value pairs:
for (const auto& dict : pt2.get_child("stuff")) {
for (const auto& kv : dict.second) {
std::cout << "key = " << kv.first << std::endl;
std::cout << "val = " << kv.second.get_value<std::string>() << std::endl;
}
}
continue with #sehe 's answer, related to the question asked by #xkm
Is it possible to get it like '[{ "name" : "some" }, { "name" : "stuffs" }]'
Yes, you can. Just treat it with an "unnamed" key which means the key with empty string.
f.g.
#include <boost/property_tree/ptree.hpp>
#include <boost/property_tree/json_parser.hpp>
#include <iostream>
using boost::property_tree::ptree;
int main()
{
std::stringstream ss;
ss << R"([{"a": 5}, {"a": 9}])";
ptree pt;
read_json(ss, pt);
for (auto& item : pt.get_child(""))
std::cout << "value is " << item.second.get<int>("a") << std::endl;
}

How to use boost::property_tree to parse JSON with array root

How can I get data from JSON with array as root node by using Boost.PropertyTree?
[
{
"ID": "cc7c3e83-9b94-4fb2-aaa3-9da458c976f7",
"Type": "VM"
}
]
The array elements are just values with a key named "" for property tree:
for (auto& array_element : pt) {
for (auto& property : array_element.second) {
std::cout << property.first << " = " << property.second.get_value<std::string>() << "\n";
}
}
Prints
ID = cc7c3e83-9b94-4fb2-aaa3-9da458c976f7
Type = VM
Live On Coliru
#include <boost/property_tree/ptree.hpp>
#include <boost/property_tree/json_parser.hpp>
#include <iostream>
using namespace boost::property_tree;
int main()
{
std::istringstream iss(R"([
{
"ID": "cc7c3e83-9b94-4fb2-aaa3-9da458c976f7",
"Type": "VM"
}
]
)");
ptree pt;
json_parser::read_json(iss, pt);
for (auto& array_element : pt) {
for (auto& property : array_element.second) {
std::cout << property.first << " = " << property.second.get_value<std::string>() << "\n";
}
}
}