JsonCpp
Une nouvelle bibliothèque pour analyser le JSON en C++11

Le , par LittleWhite

0PARTAGES

7  0 
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 :
  • 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 : Sélectionner tout
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;
Vous pouvez retrouver le projet sur GitHub.



Pour rappel, voici un exemple de données au format JSON :
Code JSON : Sélectionner tout
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

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

Une erreur dans cette actualité ? Signalez-le nous !

Avatar de Vinorcola
Membre régulier https://www.developpez.com
Le 11/01/2016 à 9:45
J'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.
2  1 
Avatar de jo_link_noir
Membre émérite https://www.developpez.com
Le 11/01/2016 à 16:57
Citation Envoyé par Ehonn Voir le message
J'ai du mal à voir / comprendre le conflit
Les boucle for-range ne fonctionnent pas alors que les fonctions d'itérateur existent. Mais sous un autre nom.

Citation Envoyé par Ehonn Voir le message
- les fonctions de la bibliothèque standard ne sont pas begin, end et flush mais std::begin, std::end et std::flush
Pourtant, il ne faudrait pas précéder par std:: les fonctions utilitaires.

Code : Sélectionner tout
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
namespace 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
Histoire que mes écris servent:
Utilisation de swap et des fonctions utilitaires
Délégation d'appel de fonctions utilitaires
2  0 
Avatar de grunk
Modérateur https://www.developpez.com
Le 11/01/2016 à 8:33
La 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.
1  0 
Avatar de akrogames
Membre actif https://www.developpez.com
Le 08/01/2016 à 19:23
Super ! 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.
0  0 
Avatar de Bousk
Rédacteur/Modérateur https://www.developpez.com
Le 11/01/2016 à 10:02
Citation Envoyé par Vinorcola Voir le message
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.
Euh.. gni ??? Je vois pas le rapport.

@grunk : donc rapidjson porte encore bien son nom ? bon à savoir
0  0 
Avatar de Vinorcola
Membre régulier https://www.developpez.com
Le 11/01/2016 à 10:21
Citation Envoyé par Bousk Voir le message
Euh.. gni ??? Je vois pas le rapport.
La 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...
0  0 
Avatar de dragonjoker59
Expert éminent sénior https://www.developpez.com
Le 11/01/2016 à 10:28
Citation Envoyé par Vinorcola Voir le message
La boucle for each
Tu parles probablement de range-based for loops?
0  0 
Avatar de Vinorcola
Membre régulier https://www.developpez.com
Le 11/01/2016 à 10:53
Je parles de la boucle :

Code : Sélectionner tout
1
2
3
4
for (const auto& child : collection)
{
    ...
}
Après, je ne connais pas forcément le nom officiel ^^
0  0 
Avatar de AoCannaille
Membre émérite https://www.developpez.com
Le 11/01/2016 à 11:14
Citation Envoyé par Vinorcola Voir le message
La 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...
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.
0  0 
Avatar de Ehonn
Membre chevronné https://www.developpez.com
Le 11/01/2016 à 14:12
Citation Envoyé par Vinorcola Voir le message
La 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...
J'ai du mal à voir / comprendre le conflit
- C++ est sensible à la casse
- les fonctions de la bibliothèque standard ne sont pas begin, end et flush mais std::begin, std::end et std::flush
0  0 
Contacter le responsable de la rubrique C++

Partenaire : Hébergement Web