How can I add members to a rapidjson document using integers as the key/name?

≡放荡痞女 提交于 2019-12-08 06:20:55

问题


I'm using a for loop and want to use the iterator, i, as the key/name when I add a member to the document. For example I want the document to look like this:

{"1":"123.321","2":"456.654"}

Here is what I have tried so far.

1. Converting i to a const char*

rapidjson::Value newDouble(6);
for(int i = 0;i<laserScan.size();i++){
    newDouble.SetDouble(laserScan[i]);
    const char* index = std::to_string(i).c_str();
    d.AddMember(index,newDouble,d.GetAllocator());
}

This generates a compiler error telling me that AddMember can only take arguments of type rapidjson::GenericValue&:

error: no matching function for call to ‘rapidjson::GenericDocument<rapidjson::UTF8<> >::AddMember(const char*&, rapidjson::Value&, rapidjson::MemoryPoolAllocator<>&)’
     d.AddMember(index,newDouble,d.GetAllocator());//add this name-value pair to the JSON string

2. Converting i to a string using rapidjson types

rapidjson::Value newDouble(6), newStringIndex(5);
for(int i = 0;i<laserScan.size();i++){    
    newDouble.SetDouble(laserScan[i]);
    const char* index = std::to_string(i).c_str();
    size = (rapidjson::SizeType)std::strlen(index);
    newStringIndex.SetString(rapidjson::StringRef(index,size));
    d.AddMember(newStringIndex,newDouble,d.GetAllocator());
}

This throws the following run-time error from Writer class:

Assertion `!hasRoot_' failed.

Why I'm Confused

Shouldn't solution #1 be the same thing as doing the following?

d.AddMember("1",newDouble,d.GetAllocator());    

This works when I try it, but I can't figure out why converting an integer to a const char* won't.


回答1:


Although you have already find an workaround, I would like to state why the original solution is not working.

The problem of solution #1 is that, the index pointer is invalid when exiting the scope.

As stated in tutorial, you can create a key string with allocator to make a copy of it:

std::string s = std::to_string(i)
Value index(s.c_str(), s.size(), d.GetAllocator()); // copy string
d.AddMember(index, newDouble, d.GetAllocator());

And for your workaround, you can simply:

dataArray.PushBack(laserScan[i], allocator);



回答2:


I found a workaround. Instead of making all the keys integers, I just added the key "indices" with the corresponding value being an array of all the indices. Then I added another array called "data" which contained an array of all the data:

rapidjson::Document document;
rapidjson::Document::AllocatorType& allocator = document.GetAllocator();
rapidjson::Value dataArray(rapidjson::kArrayType), ;

for(int i = 0;i<laserScan.size();i++){                 
    dataArray.PushBack(rapidjson::Value().SetDouble(laserScan[i]),allocator);
}
document.AddMember("data",dataArrary,allocator);


来源:https://stackoverflow.com/questions/33335892/how-can-i-add-members-to-a-rapidjson-document-using-integers-as-the-key-name

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!