0

I have a class and file "person.json". Is there any way to read that file to Data Structure like vector? my file:

{
 "students": [
{
  "name": "Jack",
  "year": 1,
  "grade": 6.95
},
{
  "name": "Paul",
  "year": 2,
  "grade": 8.54
},
{
  "name": "John",
  "year": 3,
  "grade": 9.49
},
{
  "name": "Annie",
  "year": 1,
  "grade": 3.12
}
]
} 

I would like to set person name, person year and person grade from that file, not like in my main class my main class :

int main() {

ifstream datafile("people.json");
json j;
datafile >> j;
cout << j << endl;
datafile.close();

vector<PersonClass> list;

string name = "Jonas";
float year = 420;
float grade = 69;
PersonClass *f1;
    f1 = new PersonClass;
    f1->set_name(name);
    f1->set_year(year);
    f1->set_grade(grade);

    list.push_back(*f1);
}
  • 1
    Advice -- Get a JSON library geared towards C++. Also, doing this: `PersonClass *f1; f1 = new PersonClass;` looks like Java coding. In C++, all that you need is `PersonClass f1;`. – PaulMcKenzie Sep 13 '19 at 12:34
  • https://softwarerecs.stackexchange.com/questions/48766/whats-a-good-and-easy-to-use-json-c-parser – Moia Sep 13 '19 at 12:37

1 Answers1

0

As PaulMcKenzie mentioned in the comments, get a JSON library geared towards C++. jsoncons, nlohmann, and ThorsSerializer all support conversion between JSON and C++ data structures, see How To Convert Vector To Json Object? C++ and C++ JSON Serialization. Regarding your specific question, below is a non-intrusive way of doing it in jsoncons.

#include <jsoncons/json.hpp>

class Person
{
    std::string name_;
    size_t year_;
    double grade_;
public:
    const std::string& get_name() const
    {
        return name_;
    }
    void set_name(const std::string& value)
    {
        name_ = value;
    }
    size_t get_year() const
    {
        return year_;
    }
    void set_year(size_t value)
    {
        year_ = value;
    }
    double get_grade() const
    {
        return grade_;
    }
    void set_grade(double value)
    {
        grade_ = value;
    }
};

class Students
{
    std::vector<Person> students_;
public:
    Students(const std::vector<Person>& students)
    {
        students_ = students;
    }
    const std::vector<Person>& get_students() const { return students_; }
};

JSONCONS_ALL_GETTER_SETTER_NAME_TRAITS(Person, (get_name,set_name,"name"), 
                                                (get_year,set_year, "year"), 
                                                (get_grade, set_grade, "grade"))
JSONCONS_ALL_CTOR_GETTER_NAME_TRAITS(Students, (get_students, "students"))

const std::string input = R"(
{
    "students": [
        {
            "name": "Jack",
            "year" : 1,
            "grade" : 6.95
        },
        {
          "name": "Paul",
          "year" : 2,
          "grade" : 8.54
        },
        {
          "name": "John",
          "year" : 3,
          "grade" : 9.49
        },
        {
          "name": "Annie",
          "year" : 1,
          "grade" : 3.12
        }
    ]
}
)";

int main()
{
    std::istringstream is(input);

    Students result = jsoncons::decode_json<Students>(is);

    std::cout << "(1)\n";
    for (const auto& person : result.get_students())
    {
        std::cout << person.get_name() << ", " << person.get_year() << ", " << person.get_grade() << "\n";
    }
    std::cout << "\n";

    std::ostringstream os;
    jsoncons::encode_json(result, os, jsoncons::indenting::indent);

    std::cout << "(2)\n";
    std::cout << os.str() << "\n";
}

Output:

(1)
Jack, 1, 6.95
Paul, 2, 8.54
John, 3, 9.49
Annie, 1, 3.12

(2)
{
    "students": [
        {
            "grade": 6.95,
            "name": "Jack",
            "year": 1
        },
        {
            "grade": 8.54,
            "name": "Paul",
            "year": 2
        },
        {
            "grade": 9.49,
            "name": "John",
            "year": 3
        },
        {
            "grade": 3.12,
            "name": "Annie",
            "year": 1
        }
    ]
}
Daniel
  • 728
  • 7
  • 11