1

I want to extract a specific array from a json file:

{
    "status": "OK",
    "type": "startVehicle",
    "info": {
        "idTransit": 36612,
        "timestampUTCTransit": {
            "epochUTCTransitMS": 1606935562810,
            "dateUTCTransit": "2020/12/2",
            "hourUTCTransit": "18:59:22.810"
        },
        "timestampUTCReported": {
            "epochUTCReportedMS": 1606935562810,
            "dateUTCReported": "2020/12/2",
            "hourUTCReported": "18:59:22.810"
        },
        "road": 0,
        "lane": 0,
        "xCoordinates": [
            143.6,
            -456.335
        ]
    }
}

I want extract the values of xCoordinates. This is what I tried:

#include <rapidjson/document.h>

void Vdac::addStart(std::string json_str)
{
    Document rjsondoc;

    rjsondoc.Parse(json_str.c_str());
    if(rjsondoc.HasParseError())
        slog.getLogger()->debug("Invalid json");
 
    else
    {              
        auto coordinates = rjsondoc["info"]["xCoordinates"].GetArray();

        for(SizeType i=0;i<coordinates.Size();i++)
            slog.getLogger()->debug("The start coordinates are: {0:d}",coordinates[i].GetInt());

        return;
    }
}

But I have an error when the program accesses the value. The error is:

../include/rapidjson/document.h:1737: int rapidjson::GenericValue<Encoding, Allocator>::GetInt() const [with Encoding = rapidjson::UTF8<>; Allocator = rapidjson::MemoryPoolAllocator<>]: Assertion `data_.f.flags & kIntFlag' failed.

How can I extract the value?

TrebledJ
  • 8,713
  • 7
  • 26
  • 48
cavero00
  • 11
  • 3
  • 2
    Well, you are calling `GetInt`, and the error tells you that the data is not an `int` (in `Assertion "data_.f.flags & kIntFlag' failed"`), and indeed the `xCoordinates` doesn't contain `int`s. Maybe you need `GetDouble()`? – lisyarus Dec 17 '20 at 09:44
  • Your question was "How to extract an array?", but you extracted it correctly. So the array isn't the problem and I've changed the title accordingly. It erred on reading the numbers (143.6 should be parsed as a double/float, not an int). – TrebledJ Dec 17 '20 at 09:57
  • Yes both have right, th problem was the way to access the data. The problem is solved. Thank you. – cavero00 Dec 17 '20 at 10:01

1 Answers1

0

Can't give you any help with rapidjson.

But an alternative is ThorsSerializer (note: I wrote it. So take that as you will). But it is designed to be easy to use. With zero (or very little) code that need to be written to parse the JSON into C++ objects.

Note: If you don't want to read a field just remove it.

#include <fstream>

#include "ThorSerialize/Traits.h"
#include "ThorSerialize/JsonThor.h"

struct TimeStamp
{
    long        epochUTCTransitMS;
    std::string dateUTCTransit;
    std::string hourUTCTransit;
};
// If you want to read a class then
// Add this declaration with the name of the class and the
// fields you want to read/write in JSON.
ThorsAnvil_MakeTrait(TimeStamp, epochUTCTransitMS, dateUTCTransit, hourUTCTransit);

struct Info
{
    long        idTransit;
    TimeStamp   timestampUTCTransit;
    TimeStamp   timestampUTCReported;
    int         road;
    int         lane;
    std::vector<double> xCoordinates;
};
ThorsAnvil_MakeTrait(Info, idTransit, timestampUTCTransit, timestampUTCReported, road, lane, xCoordinates);

struct Object
{
    std::string status;
    std::string type;
    Info        info;
};
ThorsAnvil_MakeTrait(Object, status, type, info);


int main()
{
    std::ifstream   data("pl1.data");

    Object      object;

    using ThorsAnvil::Serialize::jsonImporter;
    // jsonImporter to read or jsonExporter to write:
    data >> jsonImporter(object);

    std::cout << object.info.xCoordinates[0] << "\n";
}

Easy to install via brew:

> brew install thors-serializer

Build your code with:

> g++ -std=c++17 <file>.cpp -lThorSerialize17 -lThorsLogging17

Note on new M1 machs you will also need -L /opt/homebrew/lib (still working on that).

All code on github

Martin York
  • 257,169
  • 86
  • 333
  • 562