Форум программистов, компьютерный форум, киберфорум
Visual C++
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
 
Рейтинг 4.68/75: Рейтинг темы: голосов - 75, средняя оценка - 4.68
2 / 2 / 2
Регистрация: 29.06.2018
Сообщений: 139

Распарсить json при помощи библиотеки jsoncpp

14.02.2024, 15:14. Показов 27623. Ответов 20
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Кто работал с библиотекой jsoncpp подскажите, пожалуйста. Допустим есть строка, содержащяя json-код, нужно её распарсить и получить на выходе значение определённого ключа, примерно то же делает функция json_decode() в языке PHP. Пытался понять идущие с библиотекой примеры кода и ничего не понял кроме того, что мне нужно использовать класс Json::Value
Если есть решения, использующие не jsoncpp, а что-нибудь другое, то такие ответы тоже принимаются.
0
cpp_developer
Эксперт
20123 / 5690 / 1417
Регистрация: 09.04.2010
Сообщений: 22,546
Блог
14.02.2024, 15:14
Ответы с готовыми решениями:

Работа с Json-файлами. Библиотека jsoncpp C+
Здраствуйте. Начал работу с json-файлами. С подключением всё нормально, но как только начинаю работать с методами json'a начинаються...

Парсинг Json при помощи библиотеки uLkJson
доброго времени суток, подскажите как распарсить json. скачал библиотеку uLkJSON.pas но как с ней работать не знаю, есть вот такой текст ...

Ошибка при сборке библиотеки jsoncpp
Пытаю собрать библиотеку для VC++ на Builder2009. Весьма оптимистично, но все же решил попробывать. Наткнулся на такую ошибку с enum...

20
фрилансер
 Аватар для Алексей1153
6467 / 5682 / 1131
Регистрация: 11.10.2019
Сообщений: 15,144
14.02.2024, 15:35
Цитата Сообщение от Isur Посмотреть сообщение
Если есть решения, использующие не jsoncpp
Isur, мне нравится библиотека rapidjson
0
Maniac
Эксперт С++
 Аватар для ISergey
1465 / 966 / 160
Регистрация: 02.01.2009
Сообщений: 2,820
Записей в блоге: 1
17.02.2024, 16:56
Цитата Сообщение от Isur Посмотреть сообщение
Кто работал с библиотекой jsoncpp подскажите, пожалуйста. Допустим есть строка, содержащяя json-код, нужно её распарсить и получить на выходе значение определённого ключа,
пример с виду у них нормальный https://github.com/open-source... String.cpp


Цитата Сообщение от Isur Посмотреть сообщение
Если есть решения, использующие не jsoncpp, а что-нибудь другое
вот еще https://github.com/nlohmann/json
0
2 / 2 / 2
Регистрация: 29.06.2018
Сообщений: 139
29.02.2024, 17:16  [ТС]
Цитата Сообщение от Алексей1153 Посмотреть сообщение
мне нравится библиотека rapidjson
Вроде понятно, но нужна подсказка. Итак есть класс rapidjson:ocument и есть методы Parse() чтобы преобразовать текст в объект и метод GetString() чтобы выполнить обратное преобразование.

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
#include <iostream>
#include <rapidjson/document.h>
 
int main()
{
    rapidjson::Document document;
    const char* json = "{\"date\":\"2024-02-29\",\GetString():{\"temp\":2,\"feels_like\":-3,\"wind_speed\":3.4,\"wind_dir\":\"s\"}}";
    const char* member;
    
    document.Parse(json);
    if (document.HasMember("date") && document["date"].IsString()) {
        member = document["date"].GetString();
        std::cout << member << "\n";
    };
    return 0;
 }
Если член объекта будет не строковый, а числовой, то вместо GetString() нужно использовать GetInt().
А вот как обратиться к члену "weather", ведь его тип не строка, не число, а объект?
0
фрилансер
 Аватар для Алексей1153
6467 / 5682 / 1131
Регистрация: 11.10.2019
Сообщений: 15,144
29.02.2024, 19:47
Цитата Сообщение от Isur Посмотреть сообщение
А вот как обратиться к члену "weather",
а где такой, не вижу ?

Добавлено через 20 минут
Isur, накидал пример с комментами

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
    rapidjson::Document document;
    const char* json =
    u8R"({
        "date":"2024-02-29",
        "weather":
        {
            "temp":2,
            "feels_like":-3,
            "wind_speed":3.4,
            "wind_dir":"s"
        },
        "arr":[1,2,3]
    })";
 
    //под ключом "weather" - ассоциативный массив (Object) (мапа, словарь)
    //корневой элемент - тоже мапа (Object)
    //под ключом "date" - строка
    //под ключом "arr" - массив
 
    if(!document.Parse(json).HasParseError())
    {
        if(document.IsObject())
        {
            //достаём ключ со строкой
            if(const auto& date=document["date"]; date.IsString())
            {
                std::string s{date.GetString(),date.GetStringLength()};
 
                //или так
                s.assign(date.GetString(),date.GetStringLength());
 
                //а вообще, он умеет с std::string работать, но надо какой-то макрос во время компиляции врубить. Не помню
            }
 
            //достаём ключ с мапой
            if(const auto& weather=document["weather"]; weather.IsObject())
            {
                //для мапы доступны методы
                //weather.MemberCount
                //weather.MemberBegin
                //weather.MemberEnd
                //и т.д.
 
                //или просто через оператор []
                if(const auto& wind_speed=weather["wind_speed"]; wind_speed.IsFloat()) //или в общем случае - IsNumber
                {
                    auto f=wind_speed.GetFloat();
                }
            }
 
            //достаём ключ с массивом
            if(const auto& arr=document["arr"]; arr.IsArray())
            {
                //для массива доступны методы
                //arr.Count
                //arr.Begin
                //arr.End
                //и т.д.
 
                for(auto it=arr.Begin(),end=arr.End(); it!=end; ++it)
                {
                    if(it->IsNumber())
                    {
                        int i=it->GetInt();
                    }
                }
            }
        }
    }
    else
    {
        //ошибка парса
    }
Добавлено через 3 минуты
ещё есть интересный метод ParseInsitu.

Плюсы - работает быстрее и, вроде, даже память не потребляет

Минусы - на вход нужно подавать строго не константную строку (то есть, указатель на литерал сюда точно нельзя). Портит саму строку (расставляет '\0')

Но у меня было как раз много случаев, когда строка лежит в массиве, а сохранять её не нужно. Поэтому ParseInsitu у меня очень популярен
0
2 / 2 / 2
Регистрация: 29.06.2018
Сообщений: 139
29.02.2024, 20:07  [ТС]
Цитата Сообщение от Алексей1153 Посмотреть сообщение
а где такой, не вижу ?
видимо опечатался при копипастинге, ещё раз:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
#include <iostream>
#include <rapidjson/document.h>
 
int main()
{
    rapidjson::Document document;
    const char* json = "{\"date\":\"2024-02-29\",\"weather\":{\"temp\":2,\"feels_like\":-3,\"wind_speed\":3.4,\"wind_dir\":\"s\"}}";
    const char* member;
    
    document.Parse(json);
    if (document.HasMember("date") && document["date"].IsString()) {
        member = document["date"].GetString();
        std::cout << member << "\n";
    };
    return 0;
 }
0
фрилансер
 Аватар для Алексей1153
6467 / 5682 / 1131
Регистрация: 11.10.2019
Сообщений: 15,144
29.02.2024, 20:17
Isur, пример выше
0
2 / 2 / 2
Регистрация: 29.06.2018
Сообщений: 139
02.03.2024, 09:35  [ТС]
Короче понял, что мне нужно перечитывать теорию по наследованию объектов и мапы. Потому что не понимаю как это: объект document - инициализирован, а объект weather - не инициализирован, но ошибка не возникает.
0
фрилансер
 Аватар для Алексей1153
6467 / 5682 / 1131
Регистрация: 11.10.2019
Сообщений: 15,144
02.03.2024, 10:29
Isur, непонятно, о чём ты говоришь. В json нет никакого наследования и инициализации. Это структурированная разметка текста

{} - это словарь
[] - это массив
"2" - это строка
2 - это число
0
2 / 2 / 2
Регистрация: 29.06.2018
Сообщений: 139
02.03.2024, 14:14  [ТС]
Ну ладно, не буду сильно скрывать что я нуб, буду позориться по полной.
Вот это я не понимаю:
C++
1
if(const auto& weather=document["weather"]; weather.IsObject())
Мы получили объект weather из объекта document, при этом выполнили определение объекта weather внутри условия if и объект weather видимо тоже принадлежит классу rapidjson:ocument хоть это не указывается?
0
фрилансер
 Аватар для Алексей1153
6467 / 5682 / 1131
Регистрация: 11.10.2019
Сообщений: 15,144
02.03.2024, 14:19
Isur, weather - это ссылка на внутреннее представление (после парсинга) значения по ключу "weather". Это значение лежит в объекте document

далее проверяется условие - если weather это мапа, то это соответствует нашим ожиданиям. Начинаем ковыряться в weather

Добавлено через 55 секунд
Цитата Сообщение от Isur Посмотреть сообщение
не указывается
я использовал auto&, в данном случае компилятор выведет этот тип как rapidjson::Value&
0
2 / 2 / 2
Регистрация: 29.06.2018
Сообщений: 139
09.04.2024, 15:02  [ТС]
Кажись дошло, Document - это класс, наследованный от map, который в свою очередь является наследованным от string, а объекты классы map можно создавать при помощи конструкторов, не описывая. Просто наследование и конструкторы я понимаю с трудом.
0
фрилансер
 Аватар для Алексей1153
6467 / 5682 / 1131
Регистрация: 11.10.2019
Сообщений: 15,144
09.04.2024, 16:08
Isur, не нужно тут никакое наследование. Весь документ, массив, мапа и объект - это элементы json-разметки
0
2 / 2 / 2
Регистрация: 29.06.2018
Сообщений: 139
04.06.2024, 14:05  [ТС]
А если допустим мы не знаем, что document содержит ключи date и weather, как узнать список ключей. Кстати если использовать вместо rapidjson библиотеку nlohmann/json то методика будет такой же судя по примеру тут https://json.nlohmann.me/api/json/ Что такое map я так и не понял, вроде что-то относящееся с библиотеке string, но тогда причём тут?
0
фрилансер
 Аватар для Алексей1153
6467 / 5682 / 1131
Регистрация: 11.10.2019
Сообщений: 15,144
04.06.2024, 14:14
Isur, map/словарь - ассоциативный массив (ключ -> значение)

Цитата Сообщение от Isur Посмотреть сообщение
А если допустим мы не знаем, что document содержит ключи date и weather, как узнать список ключей.
проверяем, что док имеет тип мапы doc.IsObject()
затем в цикле бежим итератором
C++
1
2
3
4
5
for(auto it=map.MemberBegin(), end=map.MemberEnd(); it!=end; it++)
{
   it->name;// - это ключ
   it->value;// - это значение
}
Добавлено через 52 секунды
map.MemberCount() - количество ключей
0
2 / 2 / 2
Регистрация: 29.06.2018
Сообщений: 139
05.06.2024, 13:35  [ТС]
Цитата Сообщение от Алексей1153 Посмотреть сообщение
map/словарь - ассоциативный массив (ключ -> значение)
Ну зашибись, в С++ есть ассоциативные массивы как в PHP, которые на жаргоне называют мапами, но у Праты я этого не прочитал. Получается как всегда - невнимательность.
А попытка использовать методы MemberBegin() и MemberEnd() вызвало у меня ошибку и здесь https://rapidjson.org/document_8h.html я их описание не нашёл.
0
фрилансер
 Аватар для Алексей1153
6467 / 5682 / 1131
Регистрация: 11.10.2019
Сообщений: 15,144
05.06.2024, 13:48
Isur, может, в новых версиях что наипереименовано. Надо разбираться. Вот тут есть примеры использования https://rapidjson.org/md_doc_tutorial.html

к слову, упомянутые методы в примерах есть

Добавлено через 58 секунд
либо доки они забыли переписать после изменения исходников
0
2 / 2 / 2
Регистрация: 29.06.2018
Сообщений: 139
06.06.2024, 17:13  [ТС]
Вообще это моя первая попытка поработать с внешними библиотеками.
Попробовал как в примере в качестве типа переменной, возвращаемой функциями MemberBegin() и MemberEnd() указать auto - скомпилировалось без ошибки, видимо это какой-то внутренний тип библиотеки и их нельзя выводить.

И я не совсем понимаю то о чём писал выше. document["weather"] - это обращение к члену объекта как к члену ассоциативного массива, но при этом во всех учебниках написано, что к членам объекта обращаются как к члену структуры, через точку. Это какое-то нововведение, появившееся с C++ v.11 или ещё более поздних стандартах языка?
0
фрилансер
 Аватар для Алексей1153
6467 / 5682 / 1131
Регистрация: 11.10.2019
Сообщений: 15,144
06.06.2024, 17:19
Цитата Сообщение от Isur Посмотреть сообщение
видимо это какой-то внутренний тип
rapidjson::Value::ConstMemberIterator или rapidjson::Value::MemberIterator

но auto как раз для того и придумали, чтобы не ломать пальцы и голову об клавиатуру

Цитата Сообщение от Isur Посмотреть сообщение
document["weather"] - это обращение к члену объекта как к члену ассоциативного массива
нет, это вызов оператора rapidjson::Value::operator []. Он возвращает ссылку на rapidjson::Value

Цитата Сообщение от Isur Посмотреть сообщение
что к членам объекта обращаются как к члену структуры, через точку.
это же совсем другое. Не надо путать
0
2 / 2 / 2
Регистрация: 29.06.2018
Сообщений: 139
12.06.2024, 10:11  [ТС]
Разобрался. Нужно было выполнить все примеры из туториала, чтобы понять.
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
raxper
Эксперт
30234 / 6612 / 1498
Регистрация: 28.12.2010
Сообщений: 21,154
Блог
12.06.2024, 10:11
Помогаю со студенческими работами здесь

Распарсить строку при помощи регулярного выражения
Всем привет ,хотел бы спросить , как сделать в регулярной строке так что бы по ключевому слову начиналась фильтрация текста до ключевого...

Распарсить xml в кириллице при помощи lxml
Пытаюсь для начала просто прочитать, и посмотреть что вышло в итоге. Вместо кириллицы вылазят такие вот коды(Т например), пытался...

Как распарсить XML при помощи MSXML Parser3.0 ??
Как распарсить XML при помощи MSXML Parser3.0 в Win2k и все это сделать на VBScript?

Как спарсить array json библиотекой JsonCpp?
Доброго времени суток. Помогите пожалуйста с решением маленькой проблемы.. Есть такой обьект json: { &quot;ts&quot; : 1618405055,...

(jsoncpp) JSON замена данных или удалить и добавить
есть json файл, в нем к примеру 2 строки { &quot;hp&quot; : 10, &quot;damage&quot; : 5 } я хочу 10 поменять на 20, а 5 на 10, как мне это...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
20
Ответ Создать тему
Новые блоги и статьи
Подстановка значения реквизита справочника в табличную часть документа
Maks 10.04.2026
Алгоритм из решения ниже реализован на примере нетипового документа "ПланированиеПерсонала", разработанного в конфигурации КА2. Задача: при выборе сотрудника (справочник Сотрудники) в ТЧ документа. . .
Очистка реквизитов документа при копировании
Maks 09.04.2026
Алгоритм из решения ниже применим как для типовых, так и для нетиповых документов на самых различных конфигурациях. Задача: при копировании документа очищать определенные реквизиты и табличную. . .
модель ЗдравоСохранения 8. Подготовка к разному выполнению заданий
anaschu 08.04.2026
https:/ / github. com/ shumilovas/ med2. git main ветка * содержимое блока дэлэй из старой модели теперь внутри зайца новой модели 8ATzM_2aurI
Блокировка документа от изменений, если он открыт у другого пользователя
Maks 08.04.2026
Алгоритм из решения ниже реализован на примере нетипового документа, разработанного в конфигурации КА2. Задача: запретить редактирование документа, если он открыт у другого пользователя. / / . . .
Система безопасности+живучести для сервера-слоя интернета (сети). Двойная привязка.
Hrethgir 08.04.2026
Далее были размышления о системе безопасности. Сообщения с наклонным текстом - мои. А как нам будет можно проверить, что ссылка наша, а не подделана хулиганами, которая выбросит на другую ветку и. . .
Модель ЗдрввоСохранения 7: больше работников, больше ресурсов.
anaschu 08.04.2026
работников и заданий может быть сколько угодно, но настроено всё так, что используется пока что только 20% kYBz3eJf3jQ
Дальние перспективы сервера - слоя сети с космологическим дизайном интефейса карты и логики.
Hrethgir 07.04.2026
Дальнейшее ближайшее планирование вывело к размышлениям над дальними перспективами. И вот тут может быть даже будут нужны оценки специалистов, так как в дальних перспективах всё может очень сильно. . .
Горе от ума
kumehtar 07.04.2026
Эта мне ментальная установка, что вот прямо сейчас, мол, мне для полного счастья не хватает (нужное вписать), и когда я этого достигну - тогда и полный кайф. Одна из самых сильных ловушек на пути. . . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru