Boost Property Tree获取含点键值报错问题求助
解决Boost.PropertyTree处理INI文件中带点键名的问题
我明白你遇到的困惑了——Boost.PropertyTree的INI解析器默认会把.当作节点层级分隔符,所以你的A.B=2会被自动解析成A父节点下的B子节点,而不是一个名为A.B的独立键。这就是为什么直接用pt.get_child("A.B")会走层级查找,而转义的A\\.B找不到节点(因为解析时根本没生成这个键)。
下面分两种场景给你解决方案:
场景1:你的INI确实是层级结构(A是父节点,B是子节点)
如果你的意图是把A.B表示层级关系(比如A分组下的B项),那其实默认的解析行为是符合预期的,你可以用以下方式正确获取值:
- 直接用
get方法(自动解析路径):std::cout << pt.get<std::string>("A.B") << std::endl; // 输出2 - 或者分步获取子节点:
同时,std::cout << pt.get_child("A").get_child("B").get_value<std::string>() << std::endl; // 输出2A=1对应的值可以通过pt.get<std::string>("A")获取。
场景2:你希望A.B作为完整的键名(非层级)
如果你的INI里A.B就是一个独立的键(比如键名本身包含点),那需要修改解析器的路径分隔符,避免把.当成层级分隔。你可以在调用read_ini时指定一个不会和键名冲突的分隔符(比如';'):
修改main函数中的read_ini调用:
read_ini("sample.ini", pt, boost::property_tree::ini_parser::ini_parser_options(), ';');
这样解析后,A.B=2会被当作顶层键"A.B",值为"2",A=1是顶层键"A",值为"1"。此时你就可以直接用以下代码获取值:
std::cout << pt.get_child("A.B").get_value<std::string>() << std::endl; // 输出2
修改后的完整代码
这里给出场景2的完整代码示例:
#include <boost/property_tree/ptree.hpp> #include <boost/property_tree/ini_parser.hpp> #include <iostream> #include <string> #include <iterator> using boost::property_tree::ptree; /* Indent Json Output */ std::string indent(int level) { std::string s; for (int i = 0; i < level; i++) s += " "; return s; } /* Print tree in json format */ void printTree(ptree & pt, int level) { if (pt.empty()) { std::cerr << "\"" << pt.data() << "\""; } else { if (level) std::cerr << std::endl; std::cerr << indent(level) << "{" << std::endl; for (ptree::iterator pos = pt.begin(); pos != pt.end();) { std::cerr << indent(level + 1) << "\"" << pos-> first << "\": "; printTree(pos->second, level + 1); ++pos; if (pos != pt.end()) { std::cerr << ","; } std::cerr << std::endl; } std::cerr << indent(level) << " }"; } return; } int main() { ptree pt; // 指定路径分隔符为';',避免解析键名中的'.' read_ini("sample.ini", pt, boost::property_tree::ini_parser::ini_parser_options(), ';'); printTree(pt, 0); // 现在可以直接获取"A.B"键的值 std::cout << "\n" << pt.get_child("A.B").get_value<std::string>() << std::endl; std::cout << pt.get_child("A").get_value<std::string>() << std::endl; }
运行这段代码,printTree会输出:
{ "A": "1", "A.B": "2", "A.C": "3" }
然后正确打印出2和1。
内容的提问来源于stack exchange,提问作者raghu
相关产品推荐
相关产品推荐

