terminate called after throwing an instance of 'nlohmann::detail::parse_error'

5.2k Views Asked by At
terminate called after throwing an instance of 'nlohmann::detail::parse_error'
  what():  [json.exception.parse_error.101] parse error at line 1, column 2: syntax error while parsing object key - unexpected end of input; expected string literal

Trying to use JSON parsing from local data.json file with C++.

Code is as follows:

#include <iostream>
#include <stdio.h>
#include <string>
#include <fstream>
#include "json.hpp"
using namespace std;
using json = nlohmann::json;
int main() {
  string text;
  int x;
  string jsonguy[5];
  ifstream i("data.json");
  i >> text;
  json data = json::parse(text);
  i.close();
  return 0;
}

I have the Nlohmann json.hpp imported locally. It continues to report these errors, how do I fix it?

1

There are 1 best solutions below

2
On

In the statement i >> text;, operator>> reads a single whitespace-delimited token from the file stream and saves it into text.

And then you are trying to parse that single-token text, not the entire file. So, if there is any whitespace present in the JSON data, you would end up passing invalid JSON to parse(), hence the error.

For example, if the JSON looks like this:

{
  "key": "value"
}

The statement i >> text will extract only { and nothing else.

To fix this, get rid of the i >> text statement and just pass i itself to parse() instead, eg:

#include <iostream>
#include <fstream>
#include "json.hpp"

using json = nlohmann::json;

int main() {
  std::ifstream i("data.json");
  json data = json::parse(i);
  i.close();
  // use data as needed...
  return 0;
}

The parse() documentation says:

// (1)
template<typename InputType>
static basic_json parse(InputType&& i,
                        const parser_callback_t cb = nullptr,
                        const bool allow_exceptions = true,
                        const bool ignore_comments = false);

Deserialize from a compatible input.

InputType

A compatible input, for instance:

  • an std::istream object <--
  • a FILE pointer
  • a C-style array of characters
  • a pointer to a null-terminated string of single byte characters
  • a std::string
  • an object obj for which begin(obj) and end(obj) produces a valid pair of iterators.

If you really want to parse the file content as a std::string, see How do I read an entire file into a std::string in C++?