12

How can I read a *.json file and put the output on a std::string?

I have this sample, but I always get null on std::string.

#include <rapidjson/document.h>
#include <rapidjson/istreamwrapper.h>
#include "rapidjson/writer.h"
#include "rapidjson/stringbuffer.h"
#include <rapidjson/ostreamwrapper.h>
#include <fstream>
#include <iostream>

using namespace rapidjson;
using namespace std;

void main()
{
    ifstream ifs("input.json");
    IStreamWrapper isw(ifs);
    Document d;
    d.ParseStream(isw);

    StringBuffer buffer;
    Writer<StringBuffer> writer(buffer);
    d.Accept(writer);

    std::string jsonStr(buffer.GetString());
    if(jsonStr == "null")
        std::cout << "is null..." << std::endl; //<--always here!
    else
    {
        std::cout << jsonStr.c_str() << std::endl;

        d["ip"] = "123456789";

        ofstream ofs("output.json");
        OStreamWrapper osw(ofs);
        Writer<OStreamWrapper> writer2(osw);
        d.Accept(writer2);
    }
}

This is my json file:

{
  "ip" :  "192.168.0.100",
  "angle x": 20,
  "angle y": 0,
  "angle z": 0
}
waas1919
  • 2,365
  • 7
  • 44
  • 76
  • 1
    What are you trying to achieve exactly? If you want to read the whole file into `string`, you don't need a rapidjson for that. – Heavy Jul 21 '17 at 23:54
  • I want to read from a file, change some fields on json, write back to another file. – waas1919 Jul 22 '17 at 00:07
  • @waas1919: What does your file `input.json` contain? Post the minimal valid JSON here. Did you validate that your parsing is successful with [HasParseError()](http://rapidjson.org/classrapidjson_1_1_generic_document.html#a7607bb42b51547e44bfd4cab35d8f20e) and [GetParseError()](http://rapidjson.org/classrapidjson_1_1_generic_document.html#ab94c280c079a6837a24951cb4d8f337b)? – Azeem Jul 22 '17 at 07:01
  • @Azeem thanks for the comment. I've added my json file. – waas1919 Jul 22 '17 at 14:14
  • @Azeem d.GetParseError(); and d.HasParseError() doesnt return any errors. I guess the problem is on passing to the string... – waas1919 Jul 22 '17 at 14:20
  • @waas1919: Can you print `buffer.GetString()` before getting an `std::string` from it? What does it print? – Azeem Jul 22 '17 at 14:41
  • @waas1919: I played around with RapidJSON and your code works perfectly. Here's the [example](https://gist.github.com/iamAzeem/0a1feb4e8104b8970b26767ef344d23e) that I worked with. Make sure that there's not any other detail that you are missing. – Azeem Jul 22 '17 at 15:49
  • 2
    @Azeem Thanks! You were correct. Can you write your last comment as the answer for this thread so I can close. The buffer.GetString() was indeed showing that the file was empty and it was printing nothing. I screw up somewhere and didn't notice that the file was wrong. Your clues were very helpful :) – waas1919 Jul 22 '17 at 16:30
  • 2
    @waas1919: You are welcome! :) I'm glad that it helped. I've posted the code as answer with explanation. – Azeem Jul 22 '17 at 17:17

1 Answers1

19

You need to check for all the errors before converting to std::string. Make sure that the file is open for reading / writing and the parsing is successful i.e. the JSON is valid. GetParseError() and GetErrorOffset() are the functions to validate parsing.

I've used your example and enhanced it. Hope you won't mind. :-)

Here's a working example:

#include <iostream>
#include <fstream>
#include <cstdlib>
#include <rapidjson/document.h>
#include <rapidjson/istreamwrapper.h>
#include <rapidjson/writer.h>
#include <rapidjson/stringbuffer.h>
#include <rapidjson/ostreamwrapper.h>

int main()
{
    using namespace rapidjson;

    std::ifstream ifs { R"(C:\Test\Test.json)" };
    if ( !ifs.is_open() )
    {
        std::cerr << "Could not open file for reading!\n";
        return EXIT_FAILURE;
    }

    IStreamWrapper isw { ifs };

    Document doc {};
    doc.ParseStream( isw );

    StringBuffer buffer {};
    Writer<StringBuffer> writer { buffer };
    doc.Accept( writer );

    if ( doc.HasParseError() )
    {
        std::cout << "Error  : " << doc.GetParseError()  << '\n'
                  << "Offset : " << doc.GetErrorOffset() << '\n';
        return EXIT_FAILURE;
    }

    const std::string jsonStr { buffer.GetString() };

    std::cout << jsonStr << '\n';

    doc[ "ip" ] = "127.0.0.1";

    std::ofstream ofs { R"(C:\Test\NewTest.json)" };
    if ( !ofs.is_open() )
    {
        std::cerr << "Could not open file for writing!\n";
        return EXIT_FAILURE;
    }

    OStreamWrapper osw { ofs };
    Writer<OStreamWrapper> writer2 { osw };
    doc.Accept( writer2 );

    return EXIT_SUCCESS;
}
Azeem
  • 11,148
  • 4
  • 27
  • 40