C++ 属性树:无法设置默认属性值?
下面的代码从ini文件中读取属性。但是,我希望属性具有默认值。在读取ini文件之前,我使用C++ 属性树:无法设置默认属性值?,c++,boost,boost-propertytree,C++,Boost,Boost Propertytree,下面的代码从ini文件中读取属性。但是,我希望属性具有默认值。在读取ini文件之前,我使用put,然后使用get检索属性 如果不需要默认值,并且程序输出的testval为2,则该选项可以正常工作。但是,如果我注释掉ini文件中的条目(如图所示),程序将输出没有这样的节点(foo.bar)。换句话说,pt.put没有设置默认值。你知道为什么吗?我的电话号码是105300 #include <iostream> #include <boost/property_tree/ptree
put
,然后使用get
检索属性
如果不需要默认值,并且程序输出的testval为2
,则该选项可以正常工作。但是,如果我注释掉ini文件中的条目(如图所示),程序将输出没有这样的节点(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;
}
根据
的文档,请阅读ini()
:
清除属性树的现有内容。如果出现错误,则未修改属性树
因此,您事先所做的一切都无关紧要。根据
read_ini()
的文档:
清除属性树的现有内容。如果出现错误,则未修改属性树
因此,无论您事先做什么都无关紧要。我认为您对默认值的使用感到困惑 现在的情况是: 如果在读取文件之前将
foo.bar
的值更改为1,则读取文件将覆盖从文件读取的内容foo.bar
。如果在ini文件中注释掉bar=2
,foo.bar
没有值
如果在读取_ini后将put的值更改为1,则从该点开始的值为1是正常的put()
将foo.bar
的值设置为1
如果要在未定义foo.bar
时为get()
设置返回的默认值,请在调用get()
时指定默认值,如下所示:
testval = pt.get<int>("foo.bar", 1); // gets foo.bar from pt, or 1 if not found.
我认为您对默认值的使用感到困惑 现在的情况是: 如果在读取文件之前将
foo.bar
的值更改为1,则读取文件将覆盖从文件读取的内容foo.bar
。如果在ini文件中注释掉bar=2
,foo.bar
没有值
如果在读取_ini后将put的值更改为1,则从该点开始的值为1是正常的put()
将foo.bar
的值设置为1
如果要在未定义foo.bar
时为get()
设置返回的默认值,请在调用get()
时指定默认值,如下所示:
testval = pt.get<int>("foo.bar", 1); // gets foo.bar from pt, or 1 if not found.
但是如果我把
pt.put
放在read_ini
之后,ini文件中的值总是被忽略,并且我总是得到testval是1
?但是如果我把pt.put
放在read_ini
之后,ini文件中的值总是被忽略,而且我总是得到testval为1
…?默认版本的get
的问题是,您无法知道(a)foo.bar
是否不在ini文件中,这是一个有效的允许条件,或者(b)foo.bar
是否存在,但其值不能解析为int,必须将其标记为错误。因此,除非我误解了,否则这个版本的get
是无用的。默认值的概念是在文件中没有定义的情况下获取一个值。如果您对默认值有不同的定义,您将很难找到问题的答案。这个版本的get很有用,因为我们希望get(“foo.bar”,1)总是返回一个int。如果您想知道它是否不是int,请使用get(“foo.bar”),但是,为什么要覆盖文件中的内容?请同意您对默认值的定义。问题在于property_tree
必须负责(1)从ini文件读取密钥/val,(2)如果密钥不在文件中,则提供默认值,以及(3)如果密钥在文件中,则确认值格式正确。使用get
的默认值只能得到1和2。如果用户错误地在ini文件中输入了a
而不是1
,并且您使用了默认的get
,那么您最终会默默地忽略用户的错误并使用默认值,因此我不相信默认的get
是有用的。属性树不是作为文件验证程序构建的。它被设计成程序设置的值树。这就是文件加载和保存与类分开的原因。如果要对ini文件的内容进行类型验证,必须编写代码,将所有值读取为字符串并从中进行分析/验证。不,但它是作为数据验证器构建的,因此如果文件中的坏数据不能正确分析,它会抛出ptree\u bad\u data
。问题在于糟糕的设计:除非您准备捕捉ptree\u bad\u路径
并自己处理缺失键的默认值,并且还捕捉ptree\u bad\u数据
,然后通知用户其ini文件不正确,否则似乎无法处理实际的ini文件使用。除非你走到树上,自己检查所有的东西,这比一开始就编写解析器要困难得多。尽管如此,+1,感谢您不厌其烦地回复。默认版本的get
的问题在于,您无法知道(a)foo.bar
是否不在ini文件中,这是一个有效的允许条件,或者(b)foo.bar
是否存在,但其值无法解析为int,必须将其标记为错误。因此,除非我误解了,否则这个版本的get
是无用的。默认值的概念是在文件中没有定义的情况下获取一个值。如果您对默认值有不同的定义,您将很难找到问题的答案。这个版本的get很有用,因为我们希望get(“foo.bar”,1)总是返回一个int。如果您想知道它是否不是int,请使用get(“foo.bar”),但是,为什么要覆盖文件中的内容?请同意您的de
testval = pt.get("foo.bar", 1);