使用Boost Spirit解析十六进制值
Parsing hex values with Boost Spirit
我一直在用Boost Spirit进行解析,想知道是否有人能帮助我实现这一点。我有一个简单的解析器,它获取一个每行包含一对条目的文件。类似于以下内容:
Foo 04B
Bar 1CE
Bam 456
我下面的代码目前解析出了这一点,并将每一对放入一个std::map中,它似乎可以正常工作。我真正想做的是解析出每行上的第二个字符串,并将其转换为整数。我已经研究了int_parser,以及如何指定基,但无法获得类似的编译设置。
namespace qi = boost::spirit::qi;
std::map<std::string, std::string> results;
void insert(std::pair<std::string, std::string> p) {
results[p.first] = p.second;
}
template <typename Iterator>
bool parse_numbers(Iterator first, Iterator last) {
using qi::char_;
using qi::parse;
qi::rule<Iterator, std::pair<std::string, std::string>()> assignment;
assignment = +(~char_(' ')) >> +(char_);
bool r = parse(
first,
last,
assignment[&insert]);
if (first != last)
return false;
return r;
}
int main(int argc, char* argv[]) {
std::ifstream ifs;
std::string str;
ifs.open (argv[1], std::ifstream::in);
while (getline(ifs, str)) {
if (!parse_numbers(str.begin(), str.end())) {
std::cout << "Parsing failedn";
}
}
return 0;
}
我真正想要的是将其直接解析为std::pair <std::string, int
>。感谢您的帮助。
更多信息:
我试图声明一个与此类似的解析器:uint_parser<unsigned, 16> hex_value;
然后我试图将规则中的+(char_)替换为+(hex_value)。
我对那里发生的一切都有点困惑(尤其是语义动作[&insert]
,它似乎无端地使用了一个全局变量)。
参见Boost Spirit:";语义行为是邪恶的"?如果你对我对过早使用语义动作的立场感兴趣的话。
在这种情况下,您可以只使用std::pair<>
的Boost Fusion自适应
#include <boost/fusion/adapted/std_pair.hpp>
现在你可以简单地直接分配到地图中:
std::map<std::string, int> results;
if (ifs >> qi::phrase_match(
(qi::lexeme[+qi::graph] >> qi::int_parser<int, 16>{}) % qi::eol,
qi::blank, results)
)
Demo
正如你所猜测的,我
- 使用的
int_parser<int,16>
- 为简便起见,将输入文件替换为
std::cin
(注意您没有检查argc
…) - 使用
phrase_match
作为隐式解析输入流迭代器的好方法 - 一次解析多行
在Coliru上直播
#include <boost/fusion/adapted/std_pair.hpp>
#include <boost/spirit/include/qi.hpp>
#include <boost/spirit/include/qi_match.hpp>
#include <map>
namespace qi = boost::spirit::qi;
int main() {
std::cin.unsetf(std::ios::skipws);
std::map<std::string, int> results;
if (std::cin >> qi::phrase_match(
(qi::lexeme[+qi::graph] >> qi::int_parser<int, 16>{}) % qi::eol,
qi::blank, results)
)
{
std::cout << "Parse success:n";
for(auto& entry : results)
std::cout << "'" << entry.first << "' -> " << entry.second << "n";
} else {
std::cout << "Parse failedn";
}
}
输出:
Parse success:
'Bam' -> 1110
'Bar' -> 462
'Foo' -> 75
相关文章:
- 如何在openssl-ecc中获取十六进制格式的私钥
- 如何将包含epoch时间的十六进制字符串转换为time_t
- 将字符指针十六进制转换为字符串并保存在文本文件C++中
- 如何将一个ostringstream十六进制字符串字符对转换为单个unit8t等价的二进制值
- 如何在C++中用std::cout正确显示带十六进制的字符串文本
- 通过错误处理,在C++中可靠地获得用户十六进制输入
- 为什么mpfr_printf与十六进制浮点(%a转换说明符)的printf不同
- 在 std::无符号字符的向量处存储 int 的十六进制表示形式
- 指向存储在字符串 c++ 中的十六进制
- 读取文件中所有可能的十六进制 16 字节序列并打印每个序列
- C ++如何使用UTF8十六进制代码打印UTF8符号?
- 如何将字节数组元素替换为修改的十六进制 ASCII 符号?
- 如何在C++中将十六进制字符串转换为文本数据
- 使用 sprintf 将十六进制0xAABBCC转换为字符串"AA:BB:CC"
- 绝对编码器十六进制输入
- 为什么C++总是显示十六进制内存地址,而不仅仅是整数?
- 使用Boost进行网页抓取,返回十六进制而不是HTML
- Boost::spirit::qi -这个十六进制解析有什么问题?
- boost filesystem get permissions返回(509)dec == (1FD)十六进制.该值不在
- 使用Boost Spirit解析十六进制值