I wrote a function to save directory structure to json file.I'm using Jsoncpp libary to encode json.And I'm using c++17.But it throws a Json::LogicError
. It says that "Json::Value::operator[](ArrayIndex)
requires arrayValue".Here is the function:
void ScanFolder(string path)
{
CTYPE::PFILELIST pfl;
pfl=CTYPE::to(DIRVIEW::LoadDir(path));
JSONFILE::Encode(DIRVIEW::AddPath(path,"fconfig.json"),pfl);
for(const auto&ele : pfl.data)
if(ele.type=="Folder")
ScanFolder(DIRVIEW::AddPath(pfl.current,ele.filename));
return;
}
CTYPE
,DIRVIEW
and JSONFILE
is namespaces defined by me.Here are the Encode
function:
namespace JSONFILE
{
void Encode(string filepath,CTYPE::PFILELIST data)
{
Json::StyledWriter writer;
Json::Value arr,obj;
fstream out;
arr["Current_Folder"]=data.current;
int i=0;
for(const auto&ele : data.data)
{
arr["Files"][i]=ele.filename;
obj["Type"]=ele.type;
obj["Icon"]=ele.icon;
arr[ele.filename]=obj;
i++;
}
string jsonstr=writer.write(arr);
out.open(filepath.c_str(),ios::binary|ios::out|ios::trunc);
if(out.is_open())
out<<jsonstr<<endl;
else
return;
return;
}
};
I found that the code witch caused the error is arr[ele.filename]=obj;
.When I deleted it,the code works.I have checked the value of ele.filename
,it isn't a empty variable and it have right value like 'filename.txt'.So what should I do to fix it?
It's what it says - you're trying to perform array indexing on something that is not an array.
When you write arr["Files"]
, and arr
is a Json::Value
, a null object with that key is created for you:
Access an object value by name, create a null member if it does not exist.
So now you have a Json::Value
called arr["Files"]
, which has the "null" type.
But your next step was to treat it as an array, in arr["Files"][i]
. That doesn't work; an array is not created for you:
Access an array element (zero based index ).
If the array contains less than index element, then null value are inserted in the array so that its size is index+1. (You may need to say 'value[0u]' to get your compiler to distinguish this from the operator[] which takes a string.)
(Notice that this talks about auto-inserting elements, but not auto-creating the array itself.)
This is really easy to fix; just make that object be an array:
// ** New line here: **
arr["Files"] = Json::Value(Json::arrayValue);
for (const auto& ele : data.data)
{
arr["Files"][i] = ele.filename;
obj["Type"] = ele.type;
obj["Icon"] = ele.icon;
arr[ele.filename] = obj;
i++;
}
Here's what a minimal testcase for this issue looks like:
#include <json/value.h>
int main()
{
Json::Value val;
val[0] = "foo"; // This throws Json::LogicError
}