Prettify a JSON string in C++ from a .txt file

user7420144 picture user7420144 · Dec 15, 2017 · Viewed 7.6k times · Source

I'm currently working in C++, getting an HTTP response from a request that I write into a .txt file using ostream. This happens asynchronously and I don't want to change this.

Once the data is done being written, I want to read from the file

{"data":{"request":[{"type":"City","query":"London, United Kingdom"}],"weather":[{"date":"2013-04-21","astronomy".....

~somehow~ prettify the string using either an outside library like nlohmann/json or other(?) and then

a)print it to the console and b) save it in a different file (pretty.json)

I am having trouble understanding which method to use from: https://github.com/nlohmann/json

Any ideas how to approach this?

I was thinking getting the file line by line until I hit EOF into a sort of "buffer" and then running _json on that and saving the solution which can be displayed on the console...

My code so far

#include <cpprest/http_client.h>
#include <cpprest/filestream.h>
#include <iostream>
#include <sstream>
#include "json.hpp"



using namespace utility;                // string conversion
using namespace web;                    // URI 
using namespace web::http;              // HTTP commands
using namespace web::http::client;      // HTTP Client features
using namespace concurrency::streams;   // Asynch streams, like Node

using json = nlohmann::json;

int main()
{
auto fileStream = std::make_shared<ostream>();

// Open stream to output file.
pplx::task<void> requestTask = fstream::open_ostream(U("results.txt"))

.then([=](ostream outFile)

{
    *fileStream = outFile;

    http_client client //gets the info
    return client.request(methods::GET, stringBuilder.to_string());
})

    .then([=](http_response response)       // set up response handler
{
    printf("Received response status code:%u\n", response.status_code()); 

    return response.body().read_to_end(fileStream->streambuf());

})      

    .then([=](size_t)       // close file stream
{
    return fileStream->close();
})

    .then([=]()
{
    nlohmann::json j;
    std::ifstream i;
    i.open("results.txt"); // ?? <<< === this is where my question is
});

// Wait for all the outstanding I/O to complete, handle exceptions
try
{
    requestTask.wait();
}
catch (const std::exception &e) 
{
    printf("Error exception:%s\n", e.what());
  }


  return 0;
}

SOLUTION:

.then([=]()
    {

    // read a JSON file
    std::ifstream readFromFile("results.txt");
    if (readFromFile.is_open()) {

    nlohmann::json j;
    readFromFile >> j;

    // write prettified JSON to another file
    std::ofstream writeToFile("pretty.json");
    writeToFile << std::setw(4) << j << std::endl;

    readFromFile.close();
    writeToFile.close();
    }
    else {
        std::cout << "unable to open file";
    }

 });

Answer

UmNyobe picture UmNyobe · Dec 15, 2017

You have two choices to prettify with nlohmann.

Uses dump which produces a string

int indent = 4;
nlohmann::json data;
data.dump(indent);

Or use the stream output overload with field width set

std::ofstream o("pretty.json");
o << std::setw(4) << data << std::endl;