ibireme / yyjson

The fastest JSON library in C
https://ibireme.github.io/yyjson/doc/doxygen/html/
MIT License
3.12k stars 267 forks source link

write yyjson to file issue #50

Closed zhoufei1 closed 2 years ago

zhoufei1 commented 3 years ago

Hi ibireme Thank you very much for your last reply, but I found a problem, please help me to solve it, and I look forward to your reply

//How to find yyjson_mut_val* according to key
yyjson_mut_val* getOrCreateChildMutObj(yyjson_mut_doc doc, yyjson_mut_val parent, const std::string &key)
{
yyjson_mut_val* child = yyjson_mut_get_pointer(parent, key.data());
if (!child)// if not find, build key/value
{
child = yyjson_mut_obj(doc);
yyjson_mut_obj_add_val(doc, parent, key.data(), child);
}
return child;
}
//How to find array nodes(yyjson_mut_val*) based on key ?
yyjson_mut_val* getOrCreateArray(yyjson_mut_doc *doc, yyjson_mut_val arryParent, const std::string &key)
{
yyjson_mut_val arry = yyjson_mut_get_pointer(arryParent, key.data());
if (!arry)
{
arry = yyjson_mut_arr(doc);
yyjson_mut_obj_add_val(doc, arryParent, key.data(), arry);
}
return arry;
}

void funcLayout(yyjson_mut_doc *doc)
{
std::string key1("PATH_KEY_NODE");
std::string key2("INFO_KEY_NODE");

//case 1
{
    // auto val = getOrCreateChildMutObj(doc, doc->root, key1);
    //  yyjson_mut_val* layoutKeyNode = getOrCreateChildMutObj(doc, doc->root, key2);
    //output: It seems something went wrong
    /*
       {
        "???\"m�\u0000\u0000?K\u0001\u0000": {},
        "INFO_KEY?????�": {}
       }
    */
}

//case 2
{
    yyjson_mut_val* child = yyjson_mut_get_pointer(doc->root, key1.data());
    if (!child)
    {
        child = yyjson_mut_obj(doc);
        yyjson_mut_obj_add_val(doc, doc->root, key1.data(), child);
    }

    yyjson_mut_val* child1 = yyjson_mut_get_pointer(doc->root, key2.data());
    if (!child1)
    {
        child1 = yyjson_mut_obj(doc);
        yyjson_mut_obj_add_val(doc, doc->root, key2.data(), child1);
    }

    //output: Should be correct
    /*
        {
            "PATH_KEY_NODE": {},
            "INFO_KEY_NODE": {}
        }
    */
}

}

void writeJson()
{
yyjson_mut_doc *doc = yyjson_mut_doc_new(nullptr);
yyjson_mut_doc_set_root(doc, yyjson_mut_obj(doc));

funcLayout(doc);
//funcVerify(doc);

yyjson_write_flag flg = YYJSON_WRITE_PRETTY /*| YYJSON_WRITE_ESCAPE_UNICODE*/;
yyjson_write_err err;
yyjson_mut_write_file("config.json", doc, flg, nullptr, &err);

yyjson_mut_doc_free(doc);

}

////////
1、The result of calling at the very beginning of the program is correct 
int main(int argc, char *argv[])
{

     writeJson();  //The result of calling at the very beginning of the program is correct 

    QApplication a(argc, argv);
    MainWindow w;
    w.show();

    return a.exec();
}

2、The result of this call is wrong 
int main(int argc, char *argv[])
{

    QApplication a(argc, argv);
    MainWindow w;
    w.show();

    writeJson(); ///////////

    return a.exec();
}

////////////////////////////////// The output result of my case 2 method should be correct, but the output result of case 1 seems to be wrong. Can't you use function calls? There is still a problem with the method I use. Looking forward to your reply, thank you

///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
std::string key1("LAYOUT_PATH_KEY_NODE");
std::string key2("VERIFY_KEY_NODE");
std::string input("input_layout");
std::string output("output_layout");
std::string outlevel("output_level");

//case 1
{
    yyjson_mut_val* child1 = yyjson_mut_obj(doc);
    yyjson_mut_obj_add_val(doc, doc->root, "ROOT", child1);
    getOrCreateChildMutObj(doc, child1, "key2");
    getOrCreateChildMutObj(doc, child1, "key23");

    yyjson_mut_val* layoutKeyNode = getOrCreateChildMutObj(doc, child1, key1);
    yyjson_mut_val* arryNode = getOrCreateArray(doc, layoutKeyNode, outlevel);

     //Is there a problem with inserting data like this???
    std::vector<std::string> v{"kkkkk33333", "wwwwwwwwww", "rrrrrrrrrr", "qqqqqqqqqqqqq"};
    for(size_t i = 0; i < v.size(); ++i)
        yyjson_mut_arr_add_strcpy(doc, arryNode, v[i].data());

     #This way of access is correct, but how do I want to dynamically insert data? 
    //         yyjson_mut_arr_add_strcpy(doc, arryNode, "yyyyyyy");
  //         yyjson_mut_arr_add_strcpy(doc, arryNode, "out/debug/bin/config.json");
  //         yyjson_mut_arr_add_strcpy(doc, arryNode, "out/debug/bin/config2.json");
  //         yyjson_mut_arr_add_strcpy(doc, arryNode, "ttxttttt");

}

output: "ROOT": { "key2": {}, "key23": {}, "LAYOUT_PATH_KEY_NODE": { "�\u0000\u0000\u0000\u0000\u0000\u0000\u0000�\u0000\u0000\u0000": [ "kkkkk33333", "wwwwwwwwww", "rrrrrrrrrr", "qqqqqqqqqqqqq" ] } }

Hi ibireme how do I want to dynamically insert data?

for example : std::vectorstd::string v{"kkkkk33333", "wwwwwwwwww", "rrrrrrrrrr", "qqqqqqqqqqqqq"}; yyjson_mut_val* arryNode; //obj or arry for(size_t i = 0; i < v.size(); ++i) yyjson_mut_arr_add_strcpy(doc, arryNode, v[i].data());

The file name suffix is .cpp, then compile with g++ ,Can I use g++ to compile?

ibireme commented 3 years ago

The input of these functions should be null-terminated strings, you should use string.c_str() instead of string.data().

ibireme commented 2 years ago

Added to documentation: https://github.com/ibireme/yyjson/blob/master/doc/API.md#nul-character