Parsing JSON in C++ con Rapidjson
Per fare il parsing di una struttra JSON in C++ ci stanno molte librerie; io mi sono buttato su Rapidjson.
La documentazione sul sito ufficiale non è proprio il massimo, ma nel complesso è abbastanza semplice da implementare e includere nel nostro progetto.
Scaricate la libreria e aggiungete la cartella rapidjson al progetto; dentro ci stanno diversi file .h.
Quello che faremo è usare CURL per prendere i dati da remoto, fare il cast di CURLcode in string, e infine parsare i dati JSON.
Cominciamo come al solito dal file di intestazione:
#ifndef READ_H
#define READ_H#include <iostream>
#include <curl/curl.h>
#include <iomanip>
#include "rapidjson/document.h"
#include "rapidjson/rapidjson.h"using namespace std;
using namespace rapidjson;extern "C" int readCurlHelper(char *data, size_t size, size_t nmemb, string *buffer);
class Read {
public:
Read();
virtual ~Read();
void read(string file);
size_t curlToString(char *data, size_t size, size_t nmemb, string *buffer);
private:
string response;
string url;
CURL *curl;
CURLcode res;
struct curl_slist *headers;
Document document;
};#endif
Rispetto all'ultimo articolo, abbiamo aggiunto le librerie rapidjson e un oggetto Document.
Il nostro file di implementazione sarà una cosa del genere:
#include "read.h"
extern "C" int readCurlHelper(char *data, size_t size, size_t nmemb, string *buffer) {
Read *that = (Read *) buffer;
return that->curlToString(data, size, nmemb, NULL);
}Read::Read() {
headers = NULL;
url = "http://www.sito.com/";
}void Read::read(string file) {
curl_slist_append(headers, "Accept: application/json");
curl_slist_append(headers, "Content-Type: application/json");
curl_slist_append(headers, "charset: utf-8");
curl = curl_easy_init();
string completeUrl;
completeUrl = url.append(file);
if (curl) {
curl_easy_setopt(curl, CURLOPT_HTTPHEADER, headers);
curl_easy_setopt(curl, CURLOPT_URL, completeUrl.c_str());
curl_easy_setopt(curl, CURLOPT_HTTPGET, 1);
curl_easy_setopt(curl, CURLOPT_HTTPHEADER, headers);
curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, &readCurlHelper);
curl_easy_setopt(curl, CURLOPT_WRITEDATA, this);
res = curl_easy_perform(curl);
curl_easy_cleanup(curl);
if (res == CURLE_OK) {
const char *json = response.c_str();
if (document.Parse < 0 > (json).HasParseError()) {
cout << document.GetParseError() << "\n" << document.GetErrorOffset() << endl;
} else {
cout << left << setw(6) << "ID" << right << setw(8) << "Valore" << right << setw(30) << "Causale" << right << setw(12) << "Conto" << setw(13) << right << "Data" << endl;
cout << "----------------------------------------------------------------------" << endl;
for (SizeType i = 0; i < document.Size(); i++) {
cout << left << setw(6) << document[i]["id"].GetString()
<< right << setw(8) << document[i]["valore"].GetString()
<< right << setw(30) << document[i]["causale"].GetString()
<< right << setw(12) << document[i]["conto"].GetString()
<< right << setw(13) << document[i]["data"].GetString() << endl;
}
document.Empty();
document.Clear();
}
} else {
cerr << "Error: " << curl_easy_strerror(res) << endl;
}
response.empty();
response.clear();
}
}size_t Read::curlToString(char *data, size_t size, size_t nmemb, string *buffer) {
response.append(data, size * nmemb);
return size * nmemb;
}Read::~Read() {
}
Qui il cast da CURLcode a string ci serve per parsare la stringa JSON che riceviamo dal server.
Il tutto avviene dopo il controllo di CURL_OK.
Prima trasformiamo la stringa in un puntatore const char; questo lo diamo in pasto a rapidjson.
Se non ci sono errori di parsing stampiamo la risposta a video.
Per visualizzare meglio i dati ho usato vari setw, ma ovviamente non sono obbligatori.
Nel ciclo for stampiamo tutti i valori della stringa JSON che ci servono; le chiavi gliele passiamo come stringhe.
Dopo facciamo un pò di pulizia.
Direi che è tutto; in tre articoli abbiamo visto come usare CURL per fare richieste al server e come fare il parsing di una stringa JSON; ovviamente non è detto che il server risponda in JSON, ma ad oggi è un formato veramente comune e io lo uso spesso.
Ciao!
c++ json.curlcurlcode rapidjson
Commentami!