boost :: lexical_cast的替代品

sma*_*llB 12 c++

我正在参与挑战,只是为了切入点,在我的程序中的一个地方我需要将字符串转换为整数.我已经尝试过boost :: lexical_cast,但不幸的是它是sooo sloowwww.我想因为它执行的所有检查.我需要的是能够在没有任何检查的情况下执行此转换的内容(我知道将有效数字存储为字符串).顺便使用stringstream以天真的方式:

stringstream interpreter;
interpreter << str;
interpreter >> number;
Run Code Online (Sandbox Code Playgroud)

甚至比boost :: lexical_cast慢.
atoi是唯一的选择吗?

Gre*_*osz 19

你可以使用它,sscanf但我怀疑它比atoi处理语言环境慢.

你肯定会对阅读这个C++转换字符串到Int Speed基准测试感兴趣,该基准测试具有更快的实现atoi.

编辑:另一篇文章将不同的字符串与int实现进行比较:C++ String to Int.


seh*_*ehe 12

我可以推荐Boost Spirit(用Qi解析):

  1. 一些基准
  2. 另请参阅我的其他答案atoi上有很多整数的字符数组
  3. 一些样本用途:

.

#include <boost/spirit/include/qi.hpp>

namespace qi = boost::spirit::qi;


const char *demo1 = "1234";
const char *demo2 = "1234,2345,-777,-888";
const char *demo3 = " 1234 , 2345 , -777, -888  ";

void do_demo1()
{
    const char *begin = demo1;
    const char *iter  = begin;
    const char *end   = demo1+strlen(demo1);
    int result;

    if (qi::parse(iter, end, qi::int_, result))
        std::cout << "result = " << result << std::endl;
    else 
        std::cout << "parse failed at #" << (iter - begin) << ": " << std::string(iter, end) << std::endl;

    //// to allow for spaces, use phrase_parse instead of parse
    // if (qi::phrase_parse(begin, end, qi::int_, qi::space, result)
            //// ... etc
}

void do_demo2()
{
    const char *begin = demo2;
    const char *iter  = begin;
    const char *end   = demo2+strlen(demo2);
    std::vector<int> results;

    if (qi::parse(iter, end, qi::int_ % ',', results))
         std::cout << "results = " << results.size() << std::endl;
    else 
        std::cout << "parse failed at #" << (iter - begin) << ": " << std::string(iter, end) << std::endl;
}

void do_demo3()
{
    const char *begin = demo3;
    const char *iter  = begin;
    const char *end   = demo3+strlen(demo3);
    std::vector<int> results;

    if (qi::phrase_parse(iter, end, qi::int_ % ',', qi::space, results))
         std::cout << "results = " << results.size() << std::endl;
    else std::cout << "parse failed at #" << (iter - begin) << ": " << std::string(iter, end) << std::endl;
}

int main()
{
    do_demo1();
    do_demo2();
    do_demo3();
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

其他

请务必查看二进制(反)序列化IFF,您可以指定流(文本)格式.请参阅我最近的答案,以便比较针对序列化/反序列化的方法:

  • STL(简单的ANSI C++ 98标准库)
  • 提升精神(上图)
  • 提升序列化

那篇文章包括基准


小智 8

对于Google Summer of Code,我正在开发一个新的Boost库来解决这个问题.可以在这里找到的boost :: coerce .后端以boost :: spirit为基础,通过更简单的界面为您提供所有优势(特别是速度):

int i = boost::coerce::as<int>("23");
Run Code Online (Sandbox Code Playgroud)

要么

std::string s = boost::coerce::as<std::string>(23);
Run Code Online (Sandbox Code Playgroud)

请注意,它仍在进行中,但在实践中应该足够稳定.如果出现任何问题,请告诉我.

  • 有趣.你能评论一下为什么你不只是将lexical_cast修改为更快,以便现有用户受益,而不是制作另一个界面? (2认同)

Joh*_*nck 1

strtol可以是更好的 atoi (特别是 wrt 错误处理),并且比 lexical_cast 更快。