我需要讀取/決議的一些資料檔案具有以下樣式的標題:
level0var = value0
level0var.level1field = value1
level0var.level1array[11].level2field = value2
...
換句話說,它們看起來像嵌套的 C 風格的結構和陣列,但這些都沒有在標題中宣告:我需要在閱讀時推斷結構。
我的計劃是使用著名的nlohmann::json庫來存盤它,因為它的靈活性允許我在決議程序中更改資料的結構,并以更易讀的形式保存標題。
我讀了 as 中的作業lhs = rhs,這兩個都是字串。給定json header;,為了處理結構的未知、可變深度,我想做一些類似的事情
// std::string lhs = "level0var.level1field.level2field";
// std::string rhs = "value2";
auto current_level = header;
while ( lhs != "" ) {
auto between = lhs.substr ( 0, lhs.find_first_of ( "." ) );
lhs.erase ( 0, lhs.find_first_of ( "." ) 1 );
if ( lhs == between ) break;
current_level [ between ] = json ( {} );
current_level = current_level [ between ];
}
current_level = rhs;
std::cout << std::setw(4) << header;
對于至少具有 1 個結構級別的每一行(暫時離開陣列)。
奇怪的是,使用這個回圈,最后一行回傳的唯一東西是null,而當我使用
header [ "level0var" ] [ "level1field" ] [ "level2field" ] = rhs;
std::cout << std::setw(4) << header;
它給出了預期的結果:
{
"level0var": {
"level1field": {
"level2field": "value2"
}
}
}
Is there a way to build this hierarchical structure iteratively (without supplying it as a whole)? Once I know how to do structs, I hope the arrays will be easy!
The example I made at work does not run on coliru (which does not have the JSON library I guess).
uj5u.com熱心網友回復:
json_pointer使用正確的operator[]多載和json_pointer::get_unchecked()已經為您完成所有這些作業的函式,這確實是微不足道的。
唯一的努力是將您的.-separated 密鑰轉換為/它期望的 -separated 路徑。
#include <nlohmann/json.hpp>
#include <algorithm>
#include <iostream>
#include <string>
using json = nlohmann::json;
std::string dots_to_path(std::string key)
{
std::replace(key.begin(), key.end(), '.', '/');
key.insert(0, 1, '/');
return key;
}
int main() {
json header;
std::string lhs = "level0var.level1field.level2field";
std::string rhs = "value1";
json::json_pointer key{dots_to_path(lhs)};
header[key] = rhs;
std::cout << std::setw(4) << header;
}
為了將來參考,鏈接代碼已擴展為轉換鍵,包括陣列索引,如level0var.level1field[1].level2field-> level0var/level1field/1/level2field。
在這個階段,將原始字串標記化并簡單地附加每個標記可能會更干凈json_pointer::operator/=,但由于它不在原始問題范圍內,我將把它作為練習留給讀者。
uj5u.com熱心網友回復:
我設法用這段代碼實作了我所理解的你想要的:
using namespace nlohmann;
void main()
{
json header;
std::string lhs = "level0var.level1field.level2field";
std::string rhs = "value2";
json * current_level = &header;
while (lhs != "") {
auto between = lhs.substr(0, lhs.find_first_of("."));
lhs.erase(0, lhs.find_first_of(".") 1);
(*current_level)[between] = json({});
current_level = &((*current_level)[between]);
if (lhs == between) break;
}
*current_level = rhs;
std::cout << std::setw(4) << header;
}
幾點注意事項:
nlohmann::json_pointer盡管起初它似乎有用,但我還沒有設法使用。相反,我使用了一個“正常”的原始指標。為了參考現有的 json 結構,需要一些指標語意。我將退出回圈的條件移到了回圈的末尾(否則最里面的級別丟失了)。
老實說,我不確定我的解決方案是最好的解決方案。在這種情況下,必須非常小心地處理原始指標。但如果你愿意,你可以試試。
轉載請註明出處,本文鏈接:https://www.uj5u.com/gongcheng/456441.html
標籤:c arrays json struct nlohmann-json
