如何使用整数作为 key/name 将成员添加到 rapidjson 文档?
How can I add members to a rapidjson document using integers as the key/name?
我正在使用 for 循环并希望在向文档添加成员时使用迭代器 i 作为 key/name。例如,我希望文档看起来像这样:
{"1":"123.321","2":"456.654"}
这是我到目前为止所尝试过的方法。
1.将 i 转换为 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());
}
这会生成一个编译器错误,告诉我 AddMember 只能接受 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。使用 rapidjson types
将 i 转换为字符串
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());
}
这会从 Writer class 引发以下 运行 次错误:
Assertion `!hasRoot_' failed.
为什么我很困惑
解决方案 #1 不应该与执行以下操作相同吗?
d.AddMember("1",newDouble,d.GetAllocator());
这在我尝试时有效,但我不明白为什么将整数转换为 const char* 无效。
我找到了解决方法。我没有将所有键都设为整数,而是添加了键 "indices" ,相应的值是所有索引的数组。然后我添加了另一个名为 "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);
虽然您已经找到了解决方法,但我想说明一下为什么原始解决方案不起作用。
解决方案#1 的问题是,index
指针在退出作用域时无效。
如tutorial所述,您可以使用分配器创建一个密钥字符串来复制它:
std::string s = std::to_string(i)
Value index(s.c_str(), s.size(), d.GetAllocator()); // copy string
d.AddMember(index, newDouble, d.GetAllocator());
对于您的解决方法,您可以简单地:
dataArray.PushBack(laserScan[i], allocator);
我正在使用 for 循环并希望在向文档添加成员时使用迭代器 i 作为 key/name。例如,我希望文档看起来像这样:
{"1":"123.321","2":"456.654"}
这是我到目前为止所尝试过的方法。
1.将 i 转换为 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());
}
这会生成一个编译器错误,告诉我 AddMember 只能接受 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。使用 rapidjson types
将 i 转换为字符串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());
}
这会从 Writer class 引发以下 运行 次错误:
Assertion `!hasRoot_' failed.
为什么我很困惑
解决方案 #1 不应该与执行以下操作相同吗?
d.AddMember("1",newDouble,d.GetAllocator());
这在我尝试时有效,但我不明白为什么将整数转换为 const char* 无效。
我找到了解决方法。我没有将所有键都设为整数,而是添加了键 "indices" ,相应的值是所有索引的数组。然后我添加了另一个名为 "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);
虽然您已经找到了解决方法,但我想说明一下为什么原始解决方案不起作用。
解决方案#1 的问题是,index
指针在退出作用域时无效。
如tutorial所述,您可以使用分配器创建一个密钥字符串来复制它:
std::string s = std::to_string(i)
Value index(s.c_str(), s.size(), d.GetAllocator()); // copy string
d.AddMember(index, newDouble, d.GetAllocator());
对于您的解决方法,您可以简单地:
dataArray.PushBack(laserScan[i], allocator);