string 2 int (Между скоростью и красотой)
От: sqborev  
Дата: 05.08.07 15:06
Оценка:
Привет!

Вот тут задался вопросом: "Нормально ли это?". Кажется, что не особо хорошо.

int col=boost::lexical_cast<int>(str);


Или может есть что-то побыстрее и не менее красивое. atoi не предлагать

Хочется , чтобы преобразование было всетаки в стиле С++, а не С

Что посоветуете? stringstream? ну это поидее тоже самое, что и lexical_cast, только своими руками...
Нужно что-то красивое и не очень медленное
С уважением. Евгений Sqborev
Re: string 2 int (Между скоростью и красотой)
От: c-smile Канада http://terrainformatica.com
Дата: 05.08.07 18:34
Оценка:
Здравствуйте, sqborev, Вы писали:

S>Привет!


S>Вот тут задался вопросом: "Нормально ли это?". Кажется, что не особо хорошо.


S>
S>int col=boost::lexical_cast<int>(str);
S>


S>Или может есть что-то побыстрее и не менее красивое. atoi не предлагать


S>Хочется , чтобы преобразование было всетаки в стиле С++, а не С


S>Что посоветуете? stringstream? ну это поидее тоже самое, что и lexical_cast, только своими руками...


stringstream тут причем?

S>Нужно что-то красивое и не очень медленное


atoi() — скромное обаяние классики.
Re[2]: string 2 int (Между скоростью и красотой)
От: Sni4ok  
Дата: 05.08.07 18:57
Оценка:
Здравствуйте, c-smile, Вы писали:

CS>stringstream тут причем?


при том, что boost::lexical_cast был изначально простой обёрткой над std::stringstream,
в последних версиях вроде что-то поменялось.
Re[2]: string 2 int (Между скоростью и красотой)
От: sqborev  
Дата: 05.08.07 19:19
Оценка:
Здравствуйте, c-smile, Вы писали:

S>>Хочется , чтобы преобразование было всетаки в стиле С++, а не С


S>>Что посоветуете? stringstream? ну это поидее тоже самое, что и lexical_cast, только своими руками...


CS>stringstream тут причем?


Ну я вот только что открыл файлик lexical_cast.hpp и там вот как

#if defined(BOOST_NO_STRINGSTREAM)
std::strstream stream;
#elif defined(BOOST_NO_STD_LOCALE)
std::stringstream stream;
#else
std::basic_stringstream<char_type> stream;
#endif


Ну а вообще, читал это здесь Саттер Г. — Новые сложные задачи на C++ — страница 35

S>>Нужно что-то красивое и не очень медленное


CS>atoi() — скромное обаяние классики.


Классика С
А хочется С++
С уважением. Евгений Sqborev
Re[3]: string 2 int (Между скоростью и красотой)
От: c-smile Канада http://terrainformatica.com
Дата: 05.08.07 21:48
Оценка: 6 (2)
Здравствуйте, sqborev, Вы писали:

S>Здравствуйте, c-smile, Вы писали:


S>>>Хочется , чтобы преобразование было всетаки в стиле С++, а не С


S>>>Что посоветуете? stringstream? ну это поидее тоже самое, что и lexical_cast, только своими руками...


CS>>stringstream тут причем?


S>Ну я вот только что открыл файлик lexical_cast.hpp и там вот как


S>
S>#if defined(BOOST_NO_STRINGSTREAM)
S>std::strstream stream;
S>#elif defined(BOOST_NO_STD_LOCALE)
S>std::stringstream stream;
S>#else
S>std::basic_stringstream<char_type> stream;
S>#endif
S>


И чего? Зачем для atoi нужен stream?

S>Ну а вообще, читал это здесь Саттер Г. — Новые сложные задачи на C++ — страница 35


S>>>Нужно что-то красивое и не очень медленное


CS>>atoi() — скромное обаяние классики.


S>Классика С

S>А хочется С++

С runtime library is a part of C++ runtime. Это так, для справки

http://www.cplusplus.com/reference/clibrary/cstdlib/atoi.html

Вот преобразование itoa

  /** Integer to string converter.**/
  class itoa 
  {
    char buffer[38];
  public:
    itoa(int n, int radix = 10) { _itoa(n,buffer,radix); }
    operator const char*() { return buffer; }
  };


Использовать так:

std::string s = itoa(28);


А lexical_cast писали теоретики.
Re: string 2 int (Между скоростью и красотой)
От: korzh.pavel Россия  
Дата: 05.08.07 21:55
Оценка:
Здравствуйте, sqborev, Вы писали:

S>Привет!


S>Вот тут задался вопросом: "Нормально ли это?". Кажется, что не особо хорошо.


S>
S>int col=boost::lexical_cast<int>(str);
S>


S>Или может есть что-то побыстрее и не менее красивое. atoi не предлагать


S>Хочется , чтобы преобразование было всетаки в стиле С++, а не С


S>Что посоветуете? stringstream? ну это поидее тоже самое, что и lexical_cast, только своими руками...

S>Нужно что-то красивое и не очень медленное

Если хочешь заморочиться, то вот:
#include <string>
#include "boost/spirit/core/scanner/scanner.hpp"
#include "boost/spirit/core/primitives/numerics.hpp"

template <class IteratorT>
IteratorT string2int(IteratorT first, IteratorT last, int& val)
{
    namespace bs = boost::spirit;

    typedef bs::scanner<IteratorT, bs::scanner_policies<> >             scanner_type;
    typedef bs::int_parser<int>                                         parser_type; 
    typedef typename bs::parser_result<parser_type, scanner_type>::type result_type;
    
    scanner_type scan(first, last);

    if (result_type result = bs::int_p.parse(scan))
        val = result.value();

    return scan.first;
}

int main()
{
    std::string str= "123vs";
    int n = 0;
    string2int(str.begin(), str.end(), n);
    return 0;
}


а так ещё есть хорошая функция strtol

Замеры скорости можешь сам сделать.

Когда то кстати я делал замеры скорости функций парсинга строки в double и что интересно boost::spirit::real_p был быстрее библиотечной strtod.
Re[2]: string 2 int (Между скоростью и красотой)
От: Programador  
Дата: 05.08.07 23:38
Оценка:
Здравствуйте, korzh.pavel, Вы писали:


S>>Что посоветуете? stringstream? ну это поидее тоже самое, что и lexical_cast, только своими руками...

S>>Нужно что-то красивое и не очень медленное

KP>Если хочешь заморочиться, то вот:

KP>
KP>#include <string>
KP>#include "boost/spirit/core/scanner/scanner.hpp"
KP>#include "boost/spirit/core/primitives/numerics.hpp"

KP>template <class IteratorT>
KP>IteratorT string2int(IteratorT first, IteratorT last, int& val)
KP>{
KP>    namespace bs = boost::spirit;

KP>    typedef bs::scanner<IteratorT, bs::scanner_policies<> >             scanner_type;
KP>    typedef bs::int_parser<int>                                         parser_type; 
KP>    typedef typename bs::parser_result<parser_type, scanner_type>::type result_type;
    
KP>    scanner_type scan(first, last);

KP>    if (result_type result = bs::int_p.parse(scan))
KP>        val = result.value();

KP>    return scan.first;
KP>}

KP>int main()
KP>{
KP>    std::string str= "123vs";
KP>    int n = 0;
KP>    string2int(str.begin(), str.end(), n);
KP>    return 0;
KP>}
KP>


KP>а так ещё есть хорошая функция strtol


KP>Замеры скорости можешь сам сделать.


KP>Когда то кстати я делал замеры скорости функций парсинга строки в double и что интересно boost::spirit::real_p был быстрее библиотечной strtod.


Ну на стр2инт всего сторчки 3 нужно на чистом С
for(int v,poz;?;poz++)
 v=v*10+str[poz];

Ну еще знаки, полюбому короче чем с boost

Смысл lexical_cast чтоб использовать готовые операторы << а скорость string2int известна
lexical_cast не удачна имхо, нужно возвращать по ссылке чтоб тип определялся, ну и вообще не юзабельна, как и strlen, потому как без контроля. Я обычно sscanf( ,"%d%c" ) пользую, но это на одно поле , к сожалению sscanf не возвращает конец.

А скорость меряли
#include <iostream>
#include <utility>
#include <string>
#include <vector>
#include <fstream>
#include <algorithm>
#include <set>
#include <sstream> 
int main (int, char**)
{ 
  
  FILE *fi=fopen("123.tmp","wt");
  enum {BN=500000};
  int j; char bb[BN+5];
  for(j=BN;j--;)
    fputc('0',fi);
  fputs("--\n",fi);
  fclose(fi);

  fi=fopen("123.tmp","rt");
  fgets(bb,BN+3,fi);
  j=strlen(bb);
  fclose(fi);

  std::ifstream in("123.tmp");
  std::string is;
  getline(in,is); // уходит в себя надолго
  j=is.size();

}

std::ifstream 1 мегабайт в минуту. вот и можно прикинуть для каких размеров файлов подходит ifstream А скорость string2int побарабану, если оно конечно не делается через stringstream
Re[3]: string 2 int (Между скоростью и красотой)
От: Nuzhny Россия https://github.com/Nuzhny007
Дата: 06.08.07 05:23
Оценка:
Аналогичные тесты проводились здесь.
Re: идеальная красота это atoi
От: Аноним  
Дата: 06.08.07 10:13
Оценка:
Все остальное — малоосмысленный набор двоеточий, угловых скобок и букв, в написании которых полностью отсутствует выполняемое действие...
Re[2]: идеальная красота это atoi
От: korzh.pavel Россия  
Дата: 06.08.07 10:49
Оценка:
Здравствуйте, Аноним, Вы писали:

А>Все остальное — малоосмысленный набор двоеточий, угловых скобок и букв, в написании которых полностью отсутствует выполняемое действие...


atoi слишком примитивна, плохая диагностика исключительных ситуаций. strtol в этом плане получше будет.
Re[3]: string 2 int (Между скоростью и красотой)
От: AleksandrN Россия  
Дата: 06.08.07 10:58
Оценка:
Здравствуйте, sqborev, Вы писали:

S>Классика С

S>А хочется С++

Вам шашечки или ехать? (c)


P.S. Напиши свою функцию или класс для этой задачи — получишь то, что тебе нужно.
Re[3]: string 2 int (Между скоростью и красотой)
От: alnsn Великобритания http://nasonov.blogspot.com
Дата: 06.08.07 13:17
Оценка:
Здравствуйте, Sni4ok, Вы писали:

S>при том, что boost::lexical_cast был изначально простой обёрткой над std::stringstream,

S>в последних версиях вроде что-то поменялось.

Ага, я кое-что подкрутил, лежит в HEAD.
Вот http://accu.org/index.php/journals/1375 подробно объясняется.
Re: string 2 int (Между скоростью и красотой)
От: Шебеко Евгений  
Дата: 06.08.07 15:21
Оценка:
S>Что посоветуете? stringstream? ну это поидее тоже самое, что и lexical_cast, только своими руками...
S>Нужно что-то красивое и не очень медленное

Плюсы lexical_cast перед atoi, atol,atof:

1. Типизация
Можно например делать lexical_cast<long long>()
Что-то я не припомню в ANSI C atoll()
2. Исключение при неправильном формате.

Минус один — скорость.
lexical_cast существенно медленнее atoi
В своё время я специально тестировал. Точно не помню, кажется получалось где-то в 5-10 раз медленнее.
Использовать что-то другое плюсовое бесполезно. Как уже говорили lexical_cast просто обёртка над
string_stream. И работает с такой же скоростью (я тоже проверял)

Когда у меня стоял выбор я остановился всё же на lexical_cast, хотя конвертить надо довольно много, потому что:
1. Мне нужна проверка ошибок
2. Рано или поздно lexical_cast оптимизируют тем же atol, специализацией шаблонов это сделать раз плюнуть.

Согласен с остальным, красоты тут нет никакой. Используете в зависимости от того, что вам важнее.
Re[2]: string 2 int (Между скоростью и красотой)
От: Programador  
Дата: 06.08.07 16:29
Оценка:
Здравствуйте, Шебеко Евгений, Вы писали:

ШЕ>Минус один — скорость.

Минус 2 <тип> нужно прописывать, при смене типа по всем кастам пройтись нужно
Re[4]: string 2 int (Между скоростью и красотой)
От: Programador  
Дата: 06.08.07 16:35
Оценка:
Здравствуйте, alnsn, Вы писали:

A>Здравствуйте, Sni4ok, Вы писали:


S>>при том, что boost::lexical_cast был изначально простой обёрткой над std::stringstream,

S>>в последних версиях вроде что-то поменялось.

A>Ага, я кое-что подкрутил, лежит в HEAD.

A>Вот http://accu.org/index.php/journals/1375 подробно объясняется.

struct itoa_result
{
    char elems[12]; // assume 32-bit int
};
itoa_result itoa(int n);

A typical call of this function would look like this:

s += itoa(n).elems;


да так като поудобней будет, без bost::::::::elems
struct S12{ char s[12];};
char * itoa_result(int v,char *r=S12().s)
{ ....................
  return r;
}
Re[5]: string 2 int (Между скоростью и красотой)
От: Roman Odaisky Украина  
Дата: 07.08.07 06:33
Оценка:
Здравствуйте, Programador, Вы писали:

A>>Ага, я кое-что подкрутил, лежит в HEAD.

A>>Вот http://accu.org/index.php/journals/1375 подробно объясняется.
P>

P>

P>struct itoa_result
P>{
P>    char elems[12]; // assume 32-bit int
P>};
P>itoa_result itoa(int n);
P>

P> A typical call of this function would look like this:

P>s += itoa(n).elems;


А почему не boost::array? Да и assume можно было бы выразить и более уверенно, в виде BOOST_STATIC_ASSERT, или автоматически выбирать размер. Или это только пример из журнала, а внутри иначе?

P>да так като поудобней будет, без bost::::::::elems

P>
P>struct S12{ char s[12];};
P>char * itoa_result(int v,char *r=S12().s)
P>{ ....................
P>  return r;
P>}
P>


Ты с дубу рухнул? S12() окончит свое существование очень быстро, в любом случае раньше, чем юзер успеет использовать результат.
До последнего не верил в пирамиду Лебедева.
Re[3]: string 2 int (Между скоростью и красотой)
От: Roman Odaisky Украина  
Дата: 07.08.07 06:36
Оценка:
Здравствуйте, Programador, Вы писали:

ШЕ>>Минус один — скорость.

P>Минус 2 <тип> нужно прописывать, при смене типа по всем кастам пройтись нужно

При смене типа для lexical_cast поменяется только один typedef. При смене типа в strto* надо менять сами имена функций (strtol vs. strtod, например).
До последнего не верил в пирамиду Лебедева.
Re[3]: string 2 int (Между скоростью и красотой)
От: Шебеко Евгений  
Дата: 07.08.07 06:39
Оценка:
P>Минус 2 <тип> нужно прописывать, при смене типа по всем кастам пройтись нужно
Меня кстати тоже удивил подобный дизайн.
Незнаю почему они так сделали, может из-за наглядности, может есть какие-то более глубокие причины.
В любом случае это легко поправить.

template<typename ToType,typename FromType>
inline void do_lexical_cast(ToType& to,const FromType& from)
{
  to=boost::lexical_cast<ToType>(from);
}


P.S. А atoi не привязан к конкретному типу? Там при смене типа нужно вообще название изменить.
А тип хоть typedef'ом можно обяъвить, если есть опастность смены.
Re[6]: string 2 int (Между скоростью и красотой)
От: Programador  
Дата: 07.08.07 08:32
Оценка:
Здравствуйте, Roman Odaisky, Вы писали:

RO>Здравствуйте, Programador, Вы писали:


A>>>Ага, я кое-что подкрутил, лежит в HEAD.

A>>>Вот http://accu.org/index.php/journals/1375 подробно объясняется.
P>>

P>>

P>>struct itoa_result
P>>{
P>>    char elems[12]; // assume 32-bit int
P>>};
P>>itoa_result itoa(int n);
P>>

P>> A typical call of this function would look like this:

P>>s += itoa(n).elems;


RO>А почему не boost::array? Да и assume можно было бы выразить и более уверенно, в виде BOOST_STATIC_ASSERT, или автоматически выбирать размер. Или это только пример из журнала, а внутри иначе?

Именно boost::array возврашается boost::array::elems используется


P>>да так като поудобней будет, без bost::::::::elems

P>>
P>>struct S12{ char s[12];};
P>>char * itoa_result(int v,char *r=S12().s)
P>>{ ....................
P>>  return r;
P>>}
P>>


RO>Ты с дубу рухнул? S12() окончит свое существование очень быстро, в любом случае раньше, чем юзер успеет использовать результат.

Да такоеже время жизни как и у возвращенного boost::array до первой; покороче чем у внутреннего статического буфера, зато так можно
#include <stdio.h>
template<int N> struct ShortLine {char str[N];};

char *val2str(int v,char *f="%d",char *b=ShortLine<20>().str)
   {  sprintf(b,f,v);
      return b;
   }

void main(int, char ** )
{  char buf[64];
   printf(" %s %s %s\n",val2str(1),val2str(2),val2str(3,"pe4ataem %d",buf));
}
Re: string 2 int (Между скоростью и красотой)
От: Programador  
Дата: 07.08.07 12:10
Оценка:
вообще конструкторы в параметрах удобно. Комеау правда кастов хочет

int& ir(int  &ii=(int &)(int const &)int(0))
{ ii=9;
  return ii;
}

struct ErrorInfo
{  int errnum;
   char *msg;
   ErrorInfo():errnum(0),msg(0){};
};

ErrorInfo& do_WITH_HANDLE(int HANDLE,ErrorInfo &ei=(ErrorInfo&)(ErrorInfo const&)ErrorInfo())
{ return ei;
}
#include <iostream>
void xz()
{ ir();
  if(do_WITH_HANDLE(0).errnum)
    std::cout<<"чет не так\n";
}
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.