使用 boost-spirit 解析 ipv4 地址
Parsing ipv4 addresses using boost-spirit
我想使用 boost::spirit 来解析 ipv4 地址。这是我尝试做的:
#include <string>
#include <string.h>
#include <iostream>
#include <boost/spirit/include/qi.hpp>
#include <boost/spirit/include/phoenix_core.hpp>
#include <boost/spirit/include/phoenix_operator.hpp>
struct Ipv4 { union { uint32_t as_int; uint8_t as_char[4]; } raw; };
Ipv4 make_ipv4(uint8_t i1, uint8_t i2, uint8_t i3, uint8_t i4) {
Ipv4 ip;
ip.raw.as_char[0] = i1; ip.raw.as_char[1] = i2;
ip.raw.as_char[2] = i3; ip.raw.as_char[3] = i4;
return ip;
}
namespace qi = boost::spirit::qi;
qi::uint_parser<uint8_t, 10, 1, 3> octet;
struct Ipv4Address : qi::grammar<const char *, Ipv4()> {
Ipv4Address() : Ipv4Address::base_type(start) {
start = ( octet >> qi::lit('.') >> octet >> qi::lit('.') >>
octet >> qi::lit('.') >> octet
) [
//qi::_val = make_ipv4(1, 2, 3, 4) // working
qi::_val = make_ipv4(qi::_1, qi::_2, qi::_3, qi::_4) // compile error
]
;
}
qi::rule<const char *, Ipv4()> start;
} ipv4_address;
int main() {
Ipv4 ip;
const char * s = "1.2.3.4";
bool r = qi::parse(s, s+strlen(s), ipv4_address, ip);
std::cout << r << " " << (int)ip.raw.as_char[0] << "." <<
(int)ip.raw.as_char[1] << "." <<
(int)ip.raw.as_char[2] << "." <<
(int)ip.raw.as_char[3] << std::endl;
}
编译时,我收到以下编译错误:
/tmp/ip.cxx: 在构造函数 'Ipv4Address::Ipv4Address()' 中:/tmp/ip.cxx:26:72:错误:无法将"常量"_1_type {aka const 转换boost::p hoenix::actor>}' to 'uint8_t {aka无符号字符}",用于参数"1"到"Ipv4 make_ipv4(uint8_t, uint8_t,uint8_t,uint8_t)'
有什么提示吗?
这是"正确"的方法吗?
你需要
使用 bind
在语义动作中懒惰地绑定函数:
namespace qi = boost::spirit::qi;
namespace phx = boost::phoenix;
qi::uint_parser<uint8_t, 10, 1, 3> octet;
struct Ipv4Address : qi::grammar<const char *, Ipv4()> {
Ipv4Address() : Ipv4Address::base_type(start) {
start = ( octet >> qi::lit('.') >> octet >> qi::lit('.') >>
octet >> qi::lit('.') >> octet
) [
qi::_val = phx::bind(make_ipv4, qi::_1, qi::_2, qi::_3, qi::_4)
]
;
}
qi::rule<const char *, Ipv4()> start;
} ipv4_address;
完整示例:
#include <string>
#include <string.h>
#include <iostream>
#include <boost/spirit/include/qi.hpp>
#include <boost/spirit/include/phoenix.hpp>
struct Ipv4 { union { uint32_t as_int; uint8_t as_char[4]; } raw; };
Ipv4 make_ipv4(uint8_t i1, uint8_t i2, uint8_t i3, uint8_t i4) {
Ipv4 ip;
ip.raw.as_char[0] = i1; ip.raw.as_char[1] = i2;
ip.raw.as_char[2] = i3; ip.raw.as_char[3] = i4;
return ip;
}
namespace qi = boost::spirit::qi;
namespace phx = boost::phoenix;
qi::uint_parser<uint8_t, 10, 1, 3> octet;
struct Ipv4Address : qi::grammar<const char *, Ipv4()> {
Ipv4Address() : Ipv4Address::base_type(start) {
start = ( octet >> qi::lit('.') >> octet >> qi::lit('.') >>
octet >> qi::lit('.') >> octet
) [
qi::_val = phx::bind(make_ipv4, qi::_1, qi::_2, qi::_3, qi::_4)
]
;
}
qi::rule<const char *, Ipv4()> start;
} ipv4_address;
int main() {
Ipv4 ip;
const char * s = "1.2.3.4";
bool r = qi::parse(s, s+strlen(s), ipv4_address, ip);
std::cout << r << " " << (int)ip.raw.as_char[0] << "." <<
(int)ip.raw.as_char[1] << "." <<
(int)ip.raw.as_char[2] << "." <<
(int)ip.raw.as_char[3] << std::endl;
}
相关文章:
- 将数组的地址分配给变量并删除
- 空基优化子对象的地址
- C++ 指针的内存地址和指向数组的内存地址如何相同?
- 比较 ipv4 地址 - sockaddr_in
- CIDR 表示法中 IPv4 地址的正则表达式
- 用于in_addr结构(IPv4地址)的Mac/Windows不同格式
- 使用inet_pton()获取IPv4地址的无符号int表示形式
- 正在将IPv4/IPv6地址和端口设置为sockaddr_storage结构
- 使用 boost-spirit 解析 ipv4 地址
- 使用本地 ipv6 套接字将 UDP 发送到本地 ipv4 地址
- 如何获取 IP 地址(IPv4 为空,但存在 IPv6),内容的详细信息
- boost:asio IPv4地址和UDP通信
- 存储IPv4/IPv6地址的有效方式
- IPv4和IPv6地址的connect()行为
- 如何解析IPv4/IPv6地址块
- 从IPv4地址获取网络接口名称
- c++ winsock连接IPv4地址时被拒绝
- 从字符串中获取IPv4地址的最快方式
- 为什么 Linux 的 IPv4 地址占用 16 个字节而不是 4 个字节
- 如何从IPv4映射的IPv6地址中解析IPv4地址