C++ 使用boost::property_树解析XML中的十六进制数和十进制数
我正在用C++ 使用boost::property_树解析XML中的十六进制数和十进制数,c++,boost-propertytree,C++,Boost Propertytree,我正在用boost::property\u tree解析一个XML文件。我需要解析的数据包括常规十进制数,如42,以及十六进制数,如0xF1。例如: 0xF1 42 使用ptree::get()可以轻松解析十进制数并将其转换为int。但是,对十六进制数的相同调用失败 我可以将十六进制数解析为std::string,然后使用std::istringstream和std::hex将其转换为int。用代码演示: #include <iostream> #include <strin
boost::property\u tree
解析一个XML文件。我需要解析的数据包括常规十进制数,如42
,以及十六进制数,如0xF1
。例如:
0xF1
42
使用ptree::get()
可以轻松解析十进制数并将其转换为int
。但是,对十六进制数的相同调用失败
我可以将十六进制数解析为std::string
,然后使用std::istringstream
和std::hex
将其转换为int
。用代码演示:
#include <iostream>
#include <string>
#include <sstream>
#include <boost/property_tree/ptree.hpp>
#include <boost/property_tree/xml_parser.hpp>
using std::string;
namespace pt = boost::property_tree;
int main() {
pt::ptree tree;
try {
pt::read_xml("debug.xml", tree, pt::xml_parser::no_comments);
} catch (const pt::xml_parser_error&) {}
int hexnum;
// Doesn't work (throws exception)
try {
hexnum = tree.get<int>("hex");
} catch (const pt::ptree_bad_data&) {
std::cout << "caught bad ptree data exception";
}
// Workaround: parse as a string, then convert the string
string hexstring;
try {
hexstring = tree.get<string>("hex");
std::istringstream iss(hexstring);
iss >> std::hex >> hexnum;
if (!iss) throw std::ios_base::failure("invalid hex string");
} catch (const pt::ptree_error&) {
// get() failed
} catch (const std::ios_base::failure& fail) {
std::cout << fail.what();
}
// Parsing a regular decimal number is straightforward
int decnum;
try {
decnum = tree.get<int>("dec");
} catch (const pt::ptree_error&) {}
return 0;
}
#包括
#包括
#包括
#包括
#包括
使用std::string;
名称空间pt=boost::属性树;
int main(){
pt::ptree树;
试一试{
pt::read_xml(“debug.xml”,tree,pt::xml_解析器::无注释);
}catch(const pt::xml_解析器_error&){
int-hexnum;
//不工作(引发异常)
试一试{
hexnum=tree.get(“hex”);
}捕获(const pt::ptree\u bad\u data&){
std::cout>std::hex>>hexnum;
如果(!iss)抛出std::ios_base::failure(“无效的十六进制字符串”);
}捕获(常量pt::ptree\u错误&){
//get()失败
}捕获(const std::ios_base::failure&fail){
std::cout>std::hex
或iss>>std::dec
在std::istringstream iss
上
(如果有必要,我的编译器是VS2005。是的,'05不是'15。)stream_translator的代码看起来很简单:它只有两种方法。我想你可以编写自己的转换器并设置十六进制标志。类似这样:
/// Implementation of Translator that uses the stream overloads.
template <typename Ch, typename Traits, typename Alloc, typename E>
class stream_translator
{
typedef customize_stream<Ch, Traits, E> customized;
public:
typedef std::basic_string<Ch, Traits, Alloc> internal_type;
typedef E external_type;
explicit stream_translator(std::locale loc = std::locale())
: m_loc(loc)
{}
boost::optional<E> get_value(const internal_type &v) {
std::basic_istringstream<Ch, Traits, Alloc> iss(v);
iss.imbue(m_loc);
iss.setf(std::ios_base::hex, std::ios_base::basefield);
E e;
customized::extract(iss, e);
if(iss.fail() || iss.bad() || iss.get() != Traits::eof()) {
return boost::optional<E>();
}
return e;
}
boost::optional<internal_type> put_value(const E &v) {
std::basic_ostringstream<Ch, Traits, Alloc> oss;
oss.imbue(m_loc);
oss.setf(std::ios_base::hex, std::ios_base::basefield);
customized::insert(oss, v);
if(oss) {
return oss.str();
}
return boost::optional<internal_type>();
}
private:
std::locale m_loc;
};
只要用新的
将其“base”设置为
0
,这将自动检测数字基数。这可以(+1)工作,但并不比解决方法简单。我希望有一种方法可以做到这一点,而不必定义整个转换器。我不知道,我只是查看了boost::property_树的代码,我发现这个解决方案最明显。
template<class Type, class Translator>
Type get(const path_type &path,
const Type &default_value,
Translator tr) const;