2017-06-22 169 views
0

下面的代碼從ini文件讀取屬性。但是,我希望該屬性具有默認值。在閱讀ini文件之前,我使用put來完成此操作,然後使用get檢索該屬性。property_tree:無法設置默認屬性值?

這工作正常,如果默認不是必需的,程序輸出testval is 2。但是,如果我註釋掉ini文件中的條目(如圖所示),則程序輸出No such node (foo.bar)。換句話說,pt.put未設置默認值。任何想法爲什麼?我在升壓105300.

#include <iostream> 
#include <boost/property_tree/ptree.hpp> 
#include <boost/property_tree/ini_parser.hpp> 

int main() { 
    boost::property_tree::ptree pt; 
    int testval = 0; 

    try { 
     pt.put("foo.bar", 1);    // set a default value 
     boost::property_tree::ini_parser::read_ini("test.ini", pt); 

     testval = pt.get<int>("foo.bar"); 

    } catch(boost::property_tree::ptree_error const& e) { 
     std::cout << e.what() << '\n'; 
     return 1; 
    } 

    std::cout << "testval is " << testval << '\n'; 
    return 0; 
} 

而且test.ini是:

[foo] 
;bar = 2 

回答

2

按照該文檔read_ini()

清除屬性樹的現有內容。在出現錯誤的情況下,屬性樹未修改。

所以無論你事先做什麼都沒關係。

+0

但如果我把'pt.put' * *後的'read_ini',在ini文件中的值總是被忽略,而我總是' testval是1' ...? – EML

1

我想你對使用默認值感到困惑。

現在是: 如果您在讀取文件前將foo.bar的值更改爲1,讀取文件將覆蓋從文件讀取的內容foo.bar。如果您在ini文件中註釋掉bar=2,則foo.bar沒有任何價值。

如果更改投放到1後read_ini的價值,這是正常的,從這一點上值爲1 put()如果你想要的是設置默認設置的foo.bar爲1

值爲get()值返回時沒有定義foo.bar,您可以指定在呼叫中的默認值get()爲:

testval = pt.get<int>("foo.bar", 1); // gets foo.bar from pt, or 1 if not found. 

可以省略<int>型2個參數調用get(),因爲這給了它一個類型工作w第i個,所以這是等效於上面的電話:

testval = pt.get("foo.bar", 1); 
+0

「get」的缺省版本的問題在於,您無法知道ini文件中是否存在(a)'foo.bar',這是一個有效的允許條件,或者(b)'foo。 bar * *存在,但具有不能被解析爲int的值,必須將其標記爲錯誤。所以,除非我誤解了,這個'get'版本是沒用的。 – EML

+0

默認值的想法是如果文件中沒有定義,則獲取一個值。如果您對默認值有不同的定義,您將很難爲您的問題獲得答案。 get的這個版本非常有用,因爲我們期望get(「foo.bar」,1)總是返回一個int。如果你想知道它是不是一個整數,或不使用得到(「foo.bar」),但是,爲什麼你會覆蓋文件中的內容? –

+0

同意您的默認定義。問題是'property_tree'必須負責(1)從ini文件中讀取一個key/val的全部*,(2)如果文件中的key *不是*,則提供一個默認值,以及(3)如果文件中的鍵*是*,則確認該值是正確的。如果用戶錯誤地在ini文件中輸入了'a'而不是'1',並且使用了默認的'get',那麼最終會默默地忽略用戶的錯誤並且使用默認值,所以我不相信默認的'get'是有用的。 – EML