boost :: lexical_cast的替代品

时间:2011-06-19 17:47:38

标签: c++

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

stringstream interpreter;
interpreter << str;
interpreter >> number;

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

7 个答案:

答案 0 :(得分:19)

你可以使用sscanf来做,但我怀疑它比atoi处理区域设置慢。

您一定会对阅读此C++ Convert String to Int Speed基准测试感兴趣,该基准测试具有比atoi更快的天真实现。

编辑:另一篇比较不同字符串与int实现的帖子:C++ String to Int

答案 1 :(得分:12)

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

  1. 一些基准
  2. 另见我的其他答案atoi on a character array with lots of integers
  3. 一些示例用途:
  4. #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;
    }
    

    其他

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

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

    该帖子包括基准

答案 2 :(得分:8)

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

int i = boost::coerce::as<int>("23");

std::string s = boost::coerce::as<std::string>(23);

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

答案 3 :(得分:1)

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

答案 4 :(得分:1)

atoi / itoa函数通常更快,sscanf()也是如此。

所有这些都来自c运行时,但它们应该适合你。

答案 5 :(得分:0)

如果你真的不需要做任何检查,最快的方法就是自己转换字符串。我的意思是编写这样的代码:

int integer_from(string s)
{
  int n = 0;
  for (string::const_iterator it = s.begin(); it != s.end(); it++)
  {
    n = 10*n + (*it) - '0';
  }
  return n;
}

答案 6 :(得分:0)

如何使用stoi()。我确信它必须足够快以满足您的需求。