I am trying to open a json file that I will be working with in C++. Code that I have used successfully before fails to open the file. I am using Visual Studio 2017 on Windows 10 Pro with JSON for Modern C++ version 3.5.0.
I have a very simple function, which is supposed to open a file as input to a json object. It appears to open the file, but aborts when writing it to the json object. Originally the file to be opened was in another directory, but I moved it into the same directory as the executable while testing...but it didn't help.
Here is the very short function that fails:
json baselineOpenAndRead(string fileName) //passed string used for filename
{
json baseJObject;
cout << "we have a baseJObject" << endl;
//ifstream inFileJSON("test_file.json"); // Making this explicit made no difference
ifstream inFileJSON;
inFileJSON.open("test_file.json", ifstream::in);
cout << "we have opened json inFileJSON" << endl; // get here
inFileJSON >> baseJObject;
cout << " Can direct inFileJSON into baseJObject" << endl; //never get here; the app aborts.
inFileJSON.close();
return baseJObject;
}
This seems basically identical to the example on the nlohmann site:
// read a JSON file
std::ifstream i("file.json");
json j;
i >> j;
I just expected this to open the json file, load it into the object, and return the object. Instead, it just quits.
Thanks for any thoughts...i.e., what am I doing wrong? (I'm going to ignore that it worked before...maybe I missed something).
--Al
As requested, here is a minimal reproducible example, but it will require nlohmann's json.hpp in order to compile:
#include <iostream>
#include <fstream>
#include "json.hpp"
using json = nlohmann::json;
using namespace std;
string fileName;
json baselineOpenAndRead(string);
int main(int argC, char *argV[])
{
json baseJObject;
if (argC != 2) // check to make sure proper number of arguments are given.
{
cout << "\n\nFilename needed...";
exit(1); // number of arguments is wrong - exit program
}
else
{
fileName = argV[1];
baseJObject = baselineOpenAndRead(fileName); // opens and reads the Base Line JSON file
cout << "baseJObject returned" << endl;
}
return 0;
}
json baselineOpenAndRead(string fileName) //
{
cout << "File name: " << fileName << endl;
json baseJObject;
cout << "we have a baseJObject" << endl;
ifstream inFileJSON(fileName);
if (inFileJSON.is_open())
{
cout << "file open..." << endl;
if (nlohmann::json::accept(inFileJSON))
{
cout << "valid json" << endl;
try { inFileJSON >> baseJObject; }
catch (const std::exception &e) { std::cout << e.what() << '\n'; throw; }
}
else
{
cout << "not valid json" << endl;
}
}
else
{
cout << "file not really open" << endl;
}
inFileJSON >> baseJObject;
cout << " We can echo inFileJSON into baseJObject" << endl;
inFileJSON.close();
return baseJObject;
}
I tested it with this json file:
{
"people": [{
"name": "Scott",
"website": "stackabuse.com",
"from": "Nebraska"
},
{
"name": "Larry",
"website": "google.com",
"from": "Michigan"
},
{
"name": "Tim",
"website": "apple.com",
"from": "Alabama"
}
]
}
When I run this passing it the json above as data.json, I get the following output and then it quits:
./Test_json data.json
File name: data.json
we have a baseJObject
file open...
valid json
[json.exception.parse_error.101] parse error at line 1, column 1: syntax error while parsing value - unexpected end of input; expected '[', '{', or a literal
Without the try, it just quits. It never gets past inFileJSON >> baseJObject;
Another try that seems to work, but why?
OK. I tried this with the same main (the only changes are in the function):
json baselineOpenAndRead(string fileName) //
{
json baseJObject;
string filePath = "../baselines/" + fileName;
cout << "filePath: " << filePath << endl;
ifstream inFileJSON(fileName);
//baseJObject = json::parse(inFileJSON);
inFileJSON >> baseJObject;
cout << baseJObject << std::endl;
return baseJObject;
}
This looks basically the same to me. I tried making it ifstream inFileJSON(fileName.c_str()) on both the original and in this one. The original continued to fail, this one continued to work. Sorry this is getting so long, but I can't get decent formatting out of comments... Should I just try answering my own question instead?