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

C++ 从文本文件中读取以\x开头的十六进制值,c++,boost-propertytree,C++,Boost Propertytree,我正在使用boost::asio中的函数write()向串行设备发送数据 在代码中,我硬编码了一个字符串,该字符串由串行设备以十六进制格式检测 string test = "\x0C"; write(port, buffer(test.c_str(), test.size())); 但是,如果我从ASCII格式的配置文件中读取该值“\x0C”,它会将其检测为ASCII值 为了从配置文件中读取字符串,我使用函数boost::property\u tree::xml\u parser::read\

我正在使用boost::asio中的函数write()向串行设备发送数据

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

string test = "\x0C";
write(port, buffer(test.c_str(), test.size()));
但是,如果我从ASCII格式的配置文件中读取该值“\x0C”,它会将其检测为ASCII值

为了从配置文件中读取字符串,我使用函数boost::property\u tree::xml\u parser::read\u xml

read_xml(filename, pt);
command = pt.get<string>("conf.serial.command");
read_xml(文件名,pt);
command=pt.get(“conf.serial.command”);
如何以与另一个相同的方式处理此值?

两种方法

Xml字符引用 与提供的评论员一样,使用XML促进:


�c;
测试时:

#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
#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";
}
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();
}
所以


如果你想发送
\x0C
你必须像
“\\x0C”
那样转义反斜杠,你的意思是吗?不,当从文件中读取字符串时,它会得到\\,因此它不会转义任何内容…如何从文本文件中读取?您可以使用read()函数将其读取为二进制。最简单的方法是将其指定为xml实体:
�C。它真的必须是
\x0C
-格式吗?它可以是任何格式。那么我应该设置值&#吗?为什么&#?作为一种奖励,翻译器是可写的(实现
put_value
),如果XML文件中有一行类似于:echo-en“�C;�F”>/dev/device,会发生什么。除非我硬编码,否则它似乎不起作用。哦,逃离的乐趣。您没有说明要实现什么,但看起来您希望XML存储UNIX shell命令。假设您希望unixshell命令类似于
echo-en'\x0c\x0f'>/dev/device
,那么您应该用XML编写它:例如,-关键点:\不要期望XML是“简单的”和“可人为服务的”。是的,但所有文本编码在达到极限时都会崩溃(例如,使用二进制部分)。是的,这是另一个配置文件。它仍将字符串视为ascii。我正在使用std::system(cmd.c_str());注意如何在
echo-en&apos\x0c\x0f&apos/dev/device
我们不再关心您最初的问题(只有一个目标:XML编码命令,并且命令不再包含无法打印的字符!)。这是关键。到目前为止,我建议对命令使用/just/base64或十六进制编码:。这消除了所有的困惑(人们认为他们可以“只在XML文件中编写一个shell命令”——你不能)
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