JsonCpp
Une nouvelle bibliothèque pour analyser le JSON en C++11
Le 2016-01-08 15:51:54, par LittleWhite, Responsable 2D/3D/Jeux
JsonCpp est une énième bibliothèque pour analyser le JSON en C++ sous licence MIT. Toutefois, malgré le côté déjà vu de celle-ci, vous pourriez être intéressé par JsonCpp pour :
Autrement, celle-ci apporte les fonctionnalités habituelles permettant d'analyser les entrées au format JSON :
Voici un exemple de code utilisant JsonCpp :
Vous pouvez retrouver le projet sur GitHub.
Pour rappel, voici un exemple de données au format JSON :
Votre opinion
Quelle bibliothèque utilisez-vous pour analyser les entrées au format JSON ?
De quelles fonctionnalités avez-vous absolument besoin dans ce type de bibliothèques ?
Source
GitHub
- son utilisation du C++11 ;
- sa disponibilité en bibliothèque complètement implémentée dans les fichiers d'entêtes.
Autrement, celle-ci apporte les fonctionnalités habituelles permettant d'analyser les entrées au format JSON :
- lire et écrire des données au format JSON ;
- sérialisation/désérialisation ;
- attacher des commentaires C++ aux éléments durant l'analyse ;
- réécrire le document JSON en gardant les commentaires originaux.
Voici un exemple de code utilisant JsonCpp :
Code : |
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 | Json::Value root; // 'root' will contain the root value after parsing. std::cin >> root; // You can also read into a particular sub-value. std::cin >> root["subtree"]; // Get the value of the member of root named 'encoding', // and return 'UTF-8' if there is no such member. std::string encoding = root.get("encoding", "UTF-8" ).asString(); // Get the value of the member of root named 'plug-ins'; return a 'null' value if // there is no such member. const Json::Value plugins = root["plug-ins"]; // Iterate over the sequence elements. for ( int index = 0; index < plugins.size(); ++index ) loadPlugIn( plugins[index].asString() ); // Try other datatypes. Some are auto-convertible to others. foo::setIndentLength( root["indent"].get("length", 3).asInt() ); foo::setIndentUseSpace( root["indent"].get("use_space", true).asBool() ); // Since Json::Value has an implicit constructor for all value types, it is not // necessary to explicitly construct the Json::Value object. root["encoding"] = foo::getCurrentEncoding(); root["indent"]["length"] = foo::getCurrentIndentLength(); root["indent"]["use_space"] = foo::getCurrentIndentUseSpace(); // If you like the defaults, you can insert directly into a stream. std::cout << root; // Of course, you can write to `std::ostringstream` if you prefer. // If desired, remember to add a linefeed and flush. std::cout << std::endl; |
Pour rappel, voici un exemple de données au format JSON :
Code JSON : |
1 2 3 4 5 6 7 8 9 | { "encoding" : "UTF-8", "plug-ins" : [ "python", "c++", "ruby" ], "indent" : { "length" : 3, "use_space": true } } |
Votre opinion
Source
GitHub
-
jo_link_noirMembre expertLes boucle for-range ne fonctionnent pas alors que les fonctions d'itérateur existent. Mais sous un autre nom.
Pourtant, il ne faudrait pas précéder par std:: les fonctions utilitaires.Code : 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
44namespace kk { struct MonRange { struct iterator { /*...*/ }; iterator Begin(); iterator End(); }; MonRange::iterator begin(MonRange & r) { return r.Begin(); } MonRange::iterator end(MonRange & r) { return r.End(); } } //... std::vector<int> v; kk::MonRange r; int a[2]; for (auto x : v) {} // ok for (auto x : r) {} // ok for (auto x : a) {} // ok // dépendant du namespace std::for_each(std::begin(v), std::end(v), blahblah); // ok std::for_each(kk::begin(r), kk::end(r), blahblah); // ok std::for_each(std::begin(a), std::end(a), blahblah); // ok // avec std:: std::for_each(std::begin(v), std::end(v), blahblah); // ok std::for_each(std::begin(r), std::end(r), blahblah); // pas ok std::for_each(std::begin(a), std::end(a), blahblah); // ok // sans std:: std::for_each(begin(v), end(v), blahblah); // ok std::for_each(begin(r), end(r), blahblah); // ok std::for_each(begin(a), end(a), blahblah); // pas ok // la bonne manière de faire using std::begin; using std::end; std::for_each(begin(v), end(v), blahblah); // ok std::for_each(begin(r), end(r), blahblah); // ok std::for_each(begin(a), end(a), blahblah); // ok
Utilisation de swap et des fonctions utilitaires
Délégation d'appel de fonctions utilitairesle 11/01/2016 à 16:57 -
grunkModérateurLa première release de jsoncpp datent de 2010, mais peut être vient elle effectivement de passer au c++11. Je lai utilisé il y'a quelques mois et l'ai finalement abandonné pour rapidjson (header only également) bien plus performante.le 11/01/2016 à 8:33
-
VinorcolaMembre régulierJ'ai pas trouvé de doc en ligne... Y'a que la doc doxygen (mais pas envi de télécharger le projet juste pour voir la doc).
J'ai utilisé RapidJson aussi, mais je trouve que cette bibliothèque a un très grand défaut : les fonctions commencent par des majuscule (WTF???). Du coup, impossible d'utiliser les boucles for each, impossible d'utiliser les std::stream. Bref, une incompatibilité complète avec le C++11 standard.
Ensuite j'ai découvert celle-ci qui fonctionne plutôt bien : https://github.com/nlohmann/json
Après niveau performance, j'ai pas fait de tests. Je m'en sers pour charger des confs au lancement des programmes. Donc la performance impacte peu.le 11/01/2016 à 9:45 -
VinorcolaMembre régulierLa boucle for each utilise les fonctions begin & end. RapidJson a eu la très bonne idée de les appeler Begin et End. Du coup, ça passe pas.
L'écriture utilise la fonction Flush alors que les std::stream ont une fonction flush.
J'imagine qu'il doit y avoir d'autres incompatibilités de la sorte, mais pour le moment, je n'ai trouver que ces 2 points là, qui étaient bloquants pour moi du coup
Bref avant d'utiliser des conventions de nommage un peu farfelu, il faut penser à ce que ça implique derrière...le 11/01/2016 à 10:21 -
r0dExpert éminentBonjour.
Perso j'utilise json_spirit.
Ça fait le taf, c'est du c++11, c'est full template, mais je ne sais pas si c'est mieux que les autres car je n'ai jamais comparé.
Moi ce que j'aimerais bien, ce serait de pouvoir tester la validité du json produit avant l'exportation (écriture sur disque ou en DB). Peut-être que c'est parce que je m'y prends mal, mais étant donné que je manipule des données pleines de garbage, mes json générés sont parfois invalides.le 12/01/2016 à 15:48 -
akrogamesMembre actifSuper ! C'est une bonne nouvelle un peu de renouveau en C++ 11 pour lire/écrire du JSON car c'est pas forcément user friendly.
Je valide cette news et je m'en vais tester.le 08/01/2016 à 19:23 -
BouskRédacteur/ModérateurEuh.. gni ??? Je vois pas le rapport.
@grunk : donc rapidjson porte encore bien son nom ? bon à savoirle 11/01/2016 à 10:02 -
dragonjoker59Expert éminent séniorle 11/01/2016 à 10:28
-
VinorcolaMembre régulierJe parles de la boucle :
Code : 1
2
3
4for (const auto& child : collection) { ... }
le 11/01/2016 à 10:53 -
AoCannailleExpert confirméTes préoccupations paraissent légitimes, hésite pas à en parler sur le github, voire même d'ajouter tes fonctions avec la bonne casse et de le reproposer au créateur.le 11/01/2016 à 11:14