Create JSON array of strings with jsoncpp

G B picture G B · Sep 19, 2013 · Viewed 13.3k times · Source

I need to update an index (in JSON format) when writing a new file to disk, and since the files are categorized, I'm using an object with this kind of structure:

{ "type_1" : [ "file_1", "file_2" ], "type_2" : [ "file_3", "file_4" ] }

I thought it was an easy task for jsoncpp, but I'm probably missing something.

My code (simplified) here:

std::ifstream idx_i(_index.c_str());
Json::Value root;
Json::Value elements;
if (!idx_i.good()) { // probably doesn't exist
    root[type] = elements = Json::arrayValue;
} else {
    Json::Reader reader;
    reader.parse(idx_i, root, false);
    elements = root[type];
    if (elements.isNull()) {
        root[type] = elements = Json::arrayValue;
    }
    idx_i.close();
}
elements.append(name.c_str()); // <--- HERE LIES THE PROBLEM!!!
std::ofstream idx_o(_index.c_str());
if (idx_o.good()) {
    idx_o << root;
    idx_o.close();
} else {
    Log_ERR << "I/O error, can't write index " << _index << std::endl;
}

So, I'm opening the file, reading JSON data works, if I can't find any, I create a new array, the problem is: when I try to append a value to the array, it doesn't work, the array remains empty, and is written to file.

{ "type_1" : [], "type_2" : [] }

Tried to debug my code, and the jsoncpp calls, and everything seems to be ok, but the array is always empty.

Answer

Sga picture Sga · Mar 17, 2014

The problem arises here:

elements = root[type];

because you are creating a copy of root[type] when calling this JsonCpp API:

Value &Value::operator[]( const std::string &key )

thus not modifying root document at all. Simplest way to avoid this problem is, in your case, to not use the elements variable:

root[type].append(name.c_str());