从文本文件中读取以\ x开头的十六进制值

时间:2017-11-20 21:36:09

标签: c++ boost-propertytree

我使用boost :: asio

中的函数write()将数据发送到串行设备

在代码中,我对一个字符串进行了硬编码,该字符串由串行设备以十六进制格式检测。

string test = "\x0C";
write(port, buffer(test.c_str(), test.size()));

但是,如果我从配置文件(ASCII格式)中读取该值“\ x0C”,它会将其检测为ASCII值。

要从配置文件中读取字符串,我使用的函数是boost :: property_tree :: xml_parser :: read_xml。

read_xml(filename, pt);
command = pt.get<string>("conf.serial.command");

如何以与另一个相同的方式处理此值?

1 个答案:

答案 0 :(得分:1)

两种方法

Xml字符引用

与提供的评论者一样,使用XML character references,因为XML有助于:

<?xml version="1.0" encoding="utf-8"?>
<conf>
    <serial>
        <command>&#0c;</command>
    </serial>
</conf>

经过测试:

<强> Live On Coliru

#include <boost/property_tree/xml_parser.hpp>
#include <iostream>

using boost::property_tree::ptree;

int main() {
    ptree pt;
    {
        std::istringstream iss("<conf><serial><command>&#0c;</command></serial></conf>");
        read_xml(iss, pt);
    }

    std::string const command = pt.get<std::string>("conf.serial.command");

    std::cout << "Correct? " << std::boolalpha << (command == "\x0c") << "\n";
}Prints

Correct? true

使用翻译

你有一个观点,你可以滚动你自己的角色转义,如果你提供de-escape的代码:

struct Escaped {
    using internal_type = std::string;
    using external_type = std::string;

    std::string get_value(std::string const& input) const {
        using namespace boost::spirit::qi;
        std::string result;
        parse(input.begin(), input.end(), *(
                    "\\x" >> uint_parser<uint8_t, 16, 2, 2>{}
                    | char_) , result);
        return result;
    }
};

然后您可以将其用作PopertyTree翻译器:

<强> Live On Coliru

#include <boost/property_tree/xml_parser.hpp>
#include <boost/spirit/include/qi.hpp>
#include <iostream>

struct Escaped {
    using internal_type = std::string;
    using external_type = std::string;

    std::string get_value(std::string const& input) const {
        using namespace boost::spirit::qi;
        std::string result;
        parse(input.begin(), input.end(), *(
                    "\\x" >> uint_parser<uint8_t, 16, 2, 2>{}
                    | char_) , result);
        return result;
    }
};

int main() {
    boost::property_tree::ptree pt;
    {
        std::istringstream iss(R"(<conf><serial><command>\x0c</command></serial></conf>)");
        read_xml(iss, pt);
    }

    auto command = pt.get<std::string>("conf.serial.command", Escaped{});

    std::cout << "Correct? " << std::boolalpha << (command == "\x0c") << "\n";
}

奖金

put_value添加到译员: Live On Coliru

std::string put_value(std::string const& input) const {
    std::ostringstream result;
    for (uint8_t ch : input) {
        if (isprint(ch))
            result << ch;
        else
            result << "\\x" << std::hex << std::setw(2) << std::setfill('0') << static_cast<int>(ch);
    }
    return result.str();
}

所以

pt.put("conf.serial.command", "\x68\x65\x6c\x6c\x6f\t\x77\x6frld\n", Escaped{});
std::cout << "New value (raw): " << pt.get<std::string>("conf.serial.command") << "\n";

打印

New value (raw): hello\x09world\x0a