从文本文件中读取以 \x 开头的十六进制值
Read a hexadecimal value starting with \x from a text file
我正在使用 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");
如何以与另一个相同的方式处理这个值?
两种方法
Xml 人物参考
就像评论者提供的那样,使用 XML character references,因为 XML 有助于:
<?xml version="1.0" encoding="utf-8"?>
<conf>
<serial>
<command>�c;</command>
</serial>
</conf>
测试时:
#include <boost/property_tree/xml_parser.hpp>
#include <iostream>
using boost::property_tree::ptree;
int main() {
ptree pt;
{
std::istringstream iss("<conf><serial><command>�c;</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
使用翻译器
你说得有道理,你 可以 滚动你自己的字符转义,如果你提供反转义的代码:
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 翻译器:
#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
我正在使用 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");
如何以与另一个相同的方式处理这个值?
两种方法
Xml 人物参考
就像评论者提供的那样,使用 XML character references,因为 XML 有助于:
<?xml version="1.0" encoding="utf-8"?>
<conf>
<serial>
<command>�c;</command>
</serial>
</conf>
测试时:
#include <boost/property_tree/xml_parser.hpp>
#include <iostream>
using boost::property_tree::ptree;
int main() {
ptree pt;
{
std::istringstream iss("<conf><serial><command>�c;</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
使用翻译器
你说得有道理,你 可以 滚动你自己的字符转义,如果你提供反转义的代码:
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 翻译器:
#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