C++ C++;,boost:哪一种是解析类似字符串的最快方法tcp://adr:port/ 输入地址字符串和端口的一个int?

C++ C++;,boost:哪一种是解析类似字符串的最快方法tcp://adr:port/ 输入地址字符串和端口的一个int?,c++,string,boost,tcp,C++,String,Boost,Tcp,我们有std::stringA和tcp://adr:port/如何将其解析为地址STD::String和In为端口?< P>尽管有些人认为它不是特别的KoSee C++,但最简单的方法可能是使用sScNF: sscanf(A.c_str(), "tcp://%[^:]:%d", &addr, &port); 另一种可能是将字符串放入stringstream,在流中嵌入一个方面,将大多数字母和标点符号视为空白,然后读取地址和端口,如下所示: std::istringstream

我们有std::string
A
tcp://adr:port/如何将其解析为地址STD::String和In为端口?

< P>尽管有些人认为它不是特别的KoSee C++,但最简单的方法可能是使用sScNF:

sscanf(A.c_str(), "tcp://%[^:]:%d", &addr, &port);
另一种可能是将字符串放入stringstream,在流中嵌入一个方面,将大多数字母和标点符号视为空白,然后读取地址和端口,如下所示:

std::istringstream buffer(A);
buffer.imbue(new numeric_only);
buffer >> addr >> port;
刻面看起来像这样:

struct digits_only: std::ctype<char> 
{
    digits_only(): std::ctype<char>(get_table()) {}

    static std::ctype_base::mask const* get_table()
    {
        // everything is white-space:
        static std::vector<std::ctype_base::mask> 
            rc(std::ctype<char>::table_size,std::ctype_base::space);

        // except digits, which are digits
        std::fill(&rc['0'], &rc['9'], std::ctype_base::digit);

        // and '.', which we'll call punctuation:
        rc['.'] = std::ctype_base::punct;
        return &rc[0];
    }
};
struct digits\u仅限:std::ctype
{
digits_only():std::ctype(get_table()){
静态std::ctype_base::mask const*get_table()
{
//一切都是空白:
静态std::vector
rc(std::ctype::table_size,std::ctype_base::space);
//除了数字,它们是数字
std::fill(&rc['0'],&rc['9'],std::ctype_base::digit);
//和“.”,我们称之为标点符号:
rc['.]=std::ctype_base::punct;
返回&rc[0];
}
};

<> >代码>运算符> <代码>将空白作为“字段”之间的分隔符,因此将处理类似“代码> 192.1681.1:25/<代码>的字符串作为“两个字符串:192.1681.1”和“25”。

,尽管有些人认为它不是特别的KOSHER C++,但最简单的方法可能是使用sSCANF:

sscanf(A.c_str(), "tcp://%[^:]:%d", &addr, &port);
另一种可能是将字符串放入stringstream,在流中嵌入一个方面,将大多数字母和标点符号视为空白,然后读取地址和端口,如下所示:

std::istringstream buffer(A);
buffer.imbue(new numeric_only);
buffer >> addr >> port;
刻面看起来像这样:

struct digits_only: std::ctype<char> 
{
    digits_only(): std::ctype<char>(get_table()) {}

    static std::ctype_base::mask const* get_table()
    {
        // everything is white-space:
        static std::vector<std::ctype_base::mask> 
            rc(std::ctype<char>::table_size,std::ctype_base::space);

        // except digits, which are digits
        std::fill(&rc['0'], &rc['9'], std::ctype_base::digit);

        // and '.', which we'll call punctuation:
        rc['.'] = std::ctype_base::punct;
        return &rc[0];
    }
};
struct digits\u仅限:std::ctype
{
digits_only():std::ctype(get_table()){
静态std::ctype_base::mask const*get_table()
{
//一切都是空白:
静态std::vector
rc(std::ctype::table_size,std::ctype_base::space);
//除了数字,它们是数字
std::fill(&rc['0'],&rc['9'],std::ctype_base::digit);
//和“.”,我们称之为标点符号:
rc['.]=std::ctype_base::punct;
返回&rc[0];
}
};

operator>
将空格视为“字段”之间的分隔符,因此这会将类似于
192.168.1.1:25的内容视为两个字符串:“192.168.1.1”和“25”。

与计算机时间或程序员时间一样快吗?我不能说基准测试,但是cpp netlib框架中的uri库工作得非常好,并且非常容易使用


最快的速度是在计算机时间还是程序员时间?我不能说基准测试,但是cpp netlib框架中的uri库工作得非常好,并且非常容易使用

您可以使用类似于创建快速自定义扫描仪的工具。我还不清楚你认为什么是“最快的”——对于处理器或开发时间还是两者兼而有之?p> 您可以使用类似于创建快速自定义扫描仪的工具。我还不清楚你认为什么是“最快的”——对于处理器或开发时间还是两者兼而有之?p>
void extract(std::string const& ip, std::string& address, std::string& service)
{
   boost::regex e("tcp://(.+):(\\d+)/");
   boost::smatch what;
   if(boost::regex_match(ip, what, e, boost::match_extra))
   {
     boost::smatch::iterator it = what.begin();
     ++it; // skip the first entry..
     address = *it;
     ++it;
     service = *it;
   }
}
编辑:服务是字符串的原因是您需要它作为解析器的字符串!;)



编辑:服务是字符串的原因是您需要它作为解析器的字符串!;)

如今,一个已经包含可变数量冒号和圆点的主机部分也可能会遇到IPv6地址。然后应该按照以下步骤拆分URL。参见

如今,一个已经包含可变数量冒号和圆点的主机部分也可能遇到IPv6地址。然后应该按照以下步骤拆分URL。请参见

最快?只需做一个自定义解析器。这可以在线性扫描时间内完成。只是想一想:您可能希望支持端口的服务名称(例如telnet=23,http=80)。最快?只需做一个自定义解析器。这可以在线性扫描时间内完成。只是想一想:您可能希望支持端口的服务名称(例如telnet=23,http=80)。tsk tsk tsk。。。OP需要字符串和int…;)@杰瑞,你在
c\u str
中错过了
c\u
。不管怎样,我给+1,扫描给+1。同时提到Facets很好,但在我看来,它们看起来很难看,无法处理。IP或主机名不是一个单一的数字-你不能使用
%d
格式,不是吗
%*[^:::]
其中
*
提供了最大缓冲区大小以避免潜在的溢出?@Tony:是的,可能吧。相应地更改了。tsk tsk tsk。。。OP需要字符串和int…;)@杰瑞,你在
c\u str
中错过了
c\u
。不管怎样,我给+1,扫描给+1。同时提到Facets很好,但在我看来,它们看起来很难看,无法处理。IP或主机名不是一个单一的数字-你不能使用
%d
格式,不是吗
%*[^:::]
其中
*
提供了最大缓冲区大小以避免潜在的溢出?@Tony:是的,可能吧。相应地改变了。很好,很干净,但肯定不会是最快的,因为每次调用都会重新编译正则表达式。可能它是静态的,但也存在线程安全问题(即使使用GCC——因此是线程安全的本地静态构造——我不记得boost::regex是否安全,但可能是因为boost::smatch可能是在regex_匹配过程中唯一发生变化的东西)。尽管如此,如果“最快”确实是要求(不太可能,因为解码此字符串的时间与任何连接尝试相比都微不足道),那么您可能希望根据
sscanf
.hmm对其进行基准测试。。所以ip是adr,服务是端口?@Tony,我敢说这不是OP想要的性能!;)还有,最快的方法是什么!:)@Kambumbus,是的……不错而且干净,但肯定不会是最快的,因为每次调用都会重新编译正则表达式。可能它是静态的,但也存在线程安全问题(即使使用GCC——因此是线程安全的本地静态构造——我不记得boost::reg