Есть ли способ использовать переменную в качестве ключа в jsoncpp? - PullRequest
0 голосов
/ 08 января 2020

Я написал функцию для сохранения структуры каталогов в json файл. Я использую Jsoncpp libary для кодирования json. И я использую c ++ 17. Но он выдает Json::LogicError. Он говорит, что «Json::Value::operator[](ArrayIndex) требует arrayValue». Вот функция:

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 и JSONFILE - это пространства имен, определенные мной. Вот функция Encode:

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;
    }
};

Я обнаружил, что код, вызвавший ошибку, arr[ele.filename]=obj;. Когда я его удалил, код работает. Я проверил значение ele.filename, это не пустая переменная и оно имеет правильное значение, например «filename.txt». Что мне делать, чтобы это исправить?

1 Ответ

2 голосов
/ 09 января 2020

Это то, что он говорит - вы пытаетесь выполнить индексирование массива для чего-то, что не является массивом.

Когда вы пишете arr["Files"], а arr - это Json::Value, для вас создан пустой объект с этим ключом :

Получите доступ к значению объекта по имени, создайте нулевой элемент, если он не существует.

Итак теперь у вас есть Json::Value с именем arr["Files"], который имеет тип "null".

Но ваш следующий шаг - обработать его как массив, в arr["Files"][i]. Это не работает; массив не создан для вас :

Доступ к элементу массива (индекс на основе нуля).

Если массив содержит меньше элемента индекса, тогда ноль значение вставляется в массив так, что его размер равен index + 1. (Возможно, вам придется сказать 'value [0u]', чтобы ваш компилятор отличал guish от оператора [], который принимает строку.)

(Примечание это говорит об автоматической вставке элементов, но не об автоматическом создании самого массива.)


Это действительно легко исправить; просто сделайте этот объект массивом:

// ** 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++;
}

Вот как выглядит минимальный тестовый сценарий для этой проблемы:

#include <json/value.h>

int main()
{
    Json::Value val;
    val[0] = "foo";   // This throws Json::LogicError
}
...