Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/154.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 使用boost::property_树解析XML中的十六进制数和十进制数_C++_Boost Propertytree - Fatal编程技术网

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;