Wednesday 11 May 2016

Пример работы с json объектами в C++

Введение

К сожалению, в стандартной библиотеке С++ (STL) нет инструментов для работы с json объектами. Но существует достаточно много реализаций библиотек для всех языков программирования, в том числе и для С++. 

В данной статье приведен пример работы с json объектами с помощью библиотеки rapidjson. Все примеры из статьи есть в проекте (см. ниже).

Установка

В данном разделе приведена инструкция по установке в Microsoft Visual Studio 2012, но, почти со 100% вероятностью, она подойдет для любой версии MVS. 

  1. Если проект в MVS еще не создан, но необходимо его создать;
  2. Скачать библиотеку rapidjson. На странице проекта нужно нажать на кнопку "Download ZIP";
  3. Распаковать скаченный zip архив;
  4. Из распакованного архива в проект скопировать каталог "rapidjson-master\include\rapidjson" в каталог "rapidjson" в проекте;
  5. Открыть проект, в заголовочные файлы проекта добавить содержимое скопированного каталога.
  6. Библиотека добавлена. 

Примеры работы с библиотекой

Полный список примеров можно посмотреть на еще одном сайте проекта.

Модификация и вывод на экран

#include "rapidjson/document.h"
#include "rapidjson/writer.h"
#include "rapidjson/stringbuffer.h"
#include <iostream>
#include <string>

using namespace rapidjson;

int main() {
  std::string json = "{\"type\":\"test\",\"number\":1}";
  Document document;
  document.Parse(json.c_str());

  // Example 1: Json modification, writing Json to console
  Value& s = document["number"];
  s.SetInt(s.GetInt() + 1);

  StringBuffer buffer;
  Writer<StringBuffer> writer(buffer);
  document.Accept(writer);

  std::cout << buffer.GetString() << std::endl;
  return 0;
}
-------
Вывод на консоль:
{"type":"test","number":2}

Начинается этот пример с создания основного объекта "Document document" и парсинга json документа (в данном примере он получен из строки, но также можно либо предварительно считать данные из файла в строку, либо создать входной поток (см. следующий пример)). Далее создается ссылка на значение элемента number, которой меняется значение: "Value& s = document["number"]; s.SetInt(s.GetInt() + 1);". Пример заканчивается выводом содержимого измененного json объекта на консоль при помощи объектов классов StringBuffer и Writer<StringBuffer>.

Считывание с файла


  //Example 2: Getting json from a file
  std::ifstream ifs("test-json-file.json");
  IStreamWrapper isw(ifs);
  Document documentFromFile;

  documentFromFile.ParseStream(isw);

В данном примере создается поток ifs, затем он передается в объект-обвертки isw. Созданный объект входного потока isw передается в метод ParseStream, с помощью которого считывается json файл и инициализируется объект documentFromFile.

Итерирование по json объекту


Содержимое файла "test-json-file.json".

{
  "string": "test",
  "number": 1,
  "array": [1,2,3,4,5],
  "object": {
    "element1": 1,
    "element2": 2,
    "element3": 3
  }
}

std::string GetElementValue(const Value& val) 
{
  if (val.GetType() == Type::kNumberType)
    return std::to_string(val.GetInt());
  else if (val.GetType() == Type::kStringType)
    return val.GetString();
  else if (val.GetType() == Type::kArrayType)
    return "Array";
  else if (val.GetType() == Type::kObjectType)
    return "Object";
  return "Unknown";
}

  // Example 3: Iterating over elements
  Value::ConstMemberIterator iter = documentFromFile.MemberBegin();
  for (;iter != documentFromFile.MemberEnd(); ++iter) {
    std::cout << "Element name:" 
              <<  iter->name.GetString() 
              << "; element value: " 
              << GetElementValue(iter->value) 
              << std::endl;
  }
-------
Вывод на консоль:
Element name:string; element value: test
Element name:number; element value: 1
Element name:array; element value: Array
Element name:object; element value: Object

В данном примере создается итератор iter по объекту documentFromFile и на консоль выводятся названия json элементов и их значения.

Файл проекта

Файл проекта с примерами.




No comments:

Post a Comment