Preobrozovanie char
От: Аноним  
Дата: 18.03.04 17:47
Оценка:
|Privet all.
||Kak preobrozovat char[] v float, to est esli imeem float 0.4 poluchit char[] "0.4".
\Spasibo
Re: Preobrozovanie char
От: Alxndr Германия http://www.google.com/profiles/alexander.poluektov#buzz
Дата: 18.03.04 17:54
Оценка:
Смотри в сторону boost::lexical_cast
Re: Preobrozovanie char
От: BOPOH_N Россия  
Дата: 18.03.04 17:58
Оценка:
Здравствуйте, Аноним, Вы писали:

А>|Privet all.

А>||Kak preobrozovat char[] v float, to est esli imeem float 0.4 poluchit char[] "0.4".
А>\Spasibo

см. ф-ю _gcvt (расширение RunTime библиотеки от Microsoft)
либо sprintf(buf, "%f", mfloat)
В искустве летать есть один маленький секрет. Секрет этот в том,чтобы бросить себя изо всех сил на землю — и не попасть. Выберете погожий денек и попробуйте сами.
Re[2]: Preobrozovanie char
От: Кодт Россия  
Дата: 18.03.04 18:02
Оценка:
Здравствуйте, Alxndr, Вы писали:

A>Смотри в сторону boost::lexical_cast


Будьте проще, и люди потянутся.
char buf[32]; // вроде должно хватить
sprintf(buf, "%g", 1.23); // %g - выбирать наиболее подходящую запись: 0.123e+0001 или 1.23


или попросту,
char buf[32];
_gcvt(1.23, 12, buf); // MS-specific
Перекуём баги на фичи!
Re[2]: Preobrozovanie char
От: Кодт Россия  
Дата: 18.03.04 18:04
Оценка: +1
Здравствуйте, BOPOH_N, Вы писали:

BOP>либо sprintf(buf, "%f", mfloat)


%f — с фиксированной точкой: ±целая.дробная
%e — "инженерная" запись: ±0.мантиссапорядок
%g — автоматический выбор наиболее подходящего
Перекуём баги на фичи!
Re[3]: Preobrozovanie char
От: alexkro  
Дата: 18.03.04 21:23
Оценка:
Здравствуйте, Кодт, Вы писали:

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


A>>Смотри в сторону boost::lexical_cast


К>Будьте проще, и люди потянутся.

К>
К>char buf[32]; // вроде должно хватить
К>sprintf(buf, "%g", 1.23); // %g - выбирать наиболее подходящую запись: 0.123e+0001 или 1.23
К>


Что может быть проще:
string str = boost::lexical_cast<string>( 1.23 );

А если с буферами тягаться, то недолго и гемор ввиде security holes получить.
Re[3]: Preobrozovanie char
От: sergey_shandar США http://getboost.codeplex.com/
Дата: 19.03.04 00:26
Оценка:
Здравствуйте, Кодт, Вы писали:

A>>Смотри в сторону boost::lexical_cast


К>Будьте проще, и люди потянутся.

К>
К>char buf[32]; // вроде должно хватить
К>sprintf(buf, "%g", 1.23); // %g - выбирать наиболее подходящую запись: 0.123e+0001 или 1.23
К>


Ну тогда в сторону boost::format
#include <boost/format.hpp>
...
std::string S = (boost::format("%g") % 1.23).str();
...

getboost.codeplex.com
citylizard.codeplex.com
Re[4]: Preobrozovanie char
От: Шахтер Интернет  
Дата: 19.03.04 01:41
Оценка: 59 (9) +3 :))) :))) :))
Здравствуйте, alexkro, Вы писали:

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


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


A>>>Смотри в сторону boost::lexical_cast


К>>Будьте проще, и люди потянутся.

К>>
К>>char buf[32]; // вроде должно хватить
К>>sprintf(buf, "%g", 1.23); // %g - выбирать наиболее подходящую запись: 0.123e+0001 или 1.23
К>>


A>Что может быть проще:

A>
A>string str = boost::lexical_cast<string>( 1.23 );
A>

A>А если с буферами тягаться, то недолго и гемор ввиде security holes получить.

Да уж куда проще -- ездить из Москвы в Питер через Вашингтон.

Пересадка первая. lexical_cast -> detail::lexical_stream

    template<typename Target, typename Source>
    Target lexical_cast(Source arg)
    {
        detail::lexical_stream<Target, Source> interpreter;
        Target result;

        if(!(interpreter << arg && interpreter >> result))
            throw_exception(bad_lexical_cast(typeid(Target), typeid(Source)));
        return result;
    }


Пересадка вторая. detail::lexical_stream -> std::stringstream

            bool operator<<(const Source &input)
            {
                return !(stream << input).fail();
            }
            template<typename InputStreamable>
            bool operator>>(InputStreamable &output)
            {
                return !is_pointer<InputStreamable>::value &&
                       stream >> output &&
                       (stream >> std::ws).eof();
            }
            bool operator>>(std::string &output)
            {
                #if defined(BOOST_NO_STRINGSTREAM)
                stream << '\0';
                #endif
                output = stream.str();
                return true;
            }
            #ifndef DISABLE_WIDE_CHAR_SUPPORT
            bool operator>>(std::wstring &output)
            {
                output = stream.str();
                return true;
            }
            #endif
        private:
            typedef typename widest_char<
                typename stream_char<Target>::type,
                typename stream_char<Source>::type>::type char_type;

            #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


Пересадка третья. std::ostream -> std::num_put

        typedef num_put<_Elem, _Iter> _Nput;
                
        _Myt& operator<<(double _Val)
                {       // insert a double
                ios_base::iostate _State = ios_base::goodbit;
                const sentry _Ok(*this);

                if (_Ok)
                        {       // state okay, use facet to insert
                        const _Nput& _Nput_fac = _USE(ios_base::getloc(), _Nput);

                        _TRY_IO_BEGIN
                        if (_Nput_fac.put(_Iter(_Myios::rdbuf()), *this,
                                _Myios::fill(), _Val).failed())
                                _State |= ios_base::badbit;
                        _CATCH_IO_END
                        }

                _Myios::setstate(_State);
                return (*this);
                }


Пересадка четвертая. std::num_put -> sprintf

        _OutIt put(_OutIt _Dest,
                ios_base& _Iosbase, _Elem _Fill, double _Val) const
                {       // put formatted double to _Dest
                return (do_put(_Dest, _Iosbase, _Fill, _Val));
                }
                                
        _VIRTUAL _OutIt do_put(_OutIt _Dest,
                ios_base& _Iosbase, _Elem _Fill, double _Val) const
                {       // put formatted double to _Dest
                char _Buf[_MAX_EXP_DIG + _MAX_SIG_DIG + 64], _Fmt[8];
                streamsize _Precision = _Iosbase.precision() <= 0
                        && !(_Iosbase.flags() & ios_base::fixed)
                                ? 6 : _Iosbase.precision();     // desired precision
                int _Significance = _MAX_SIG_DIG < _Precision
                        ? _MAX_SIG_DIG : (int)_Precision;       // actual sprintf precision
                _Precision -= _Significance;
                size_t _Beforepoint = 0;        // zeros to add before decimal point
                size_t _Afterpoint = 0; // zeros to add after decimal point

                if ((_Iosbase.flags() & ios_base::floatfield) == ios_base::fixed)
                        {       // scale silly fixed-point value
                        bool _Signed = _Val < 0;
                        if (_Signed)
                                _Val = -_Val;

                        for (; 1e35 <= _Val && _Beforepoint < 5000; _Beforepoint += 10)
                                _Val /= 1e10;   // drop 10 zeros before decimal point

                        if (0 < _Val)
                                for (; 10 <= _Precision && _Val <= 1e-35
                                        && _Afterpoint < 5000; _Afterpoint += 10)
                                        {       // drop 10 zeros after decimal point
                                        _Val *= 1e10;
                                        _Precision -= 10;
                                        }

                        if (_Signed)
                                _Val = -_Val;
                        }

                return (_Fput(_Dest, _Iosbase, _Fill, _Buf,
                        _Beforepoint, _Afterpoint, _Precision,
                                ::sprintf(_Buf, _Ffmt(_Fmt, 0, _Iosbase.flags()),
                                        _Significance, _Val))); // convert and put
                }


Обратите внимание, как изящно, на лету формируется строка формата для передачи в sprintf.
Маршрут ещё не закончен. В его конце вы наёдёте _fcvt, _gcvt или что-то подобное. А в самых потрохах -- кусок на ассемблере, который и делает реальную работу.

И последнее:

Не надо путать программирование и идиотию. Авторы boost а, во всяком случае этой его части, программистами названы быть не могут. Ими вообще должны заниматься специальные люди в былых халатах.
... << RSDN@Home 1.1.0 stable >>
В XXI век с CCore.
Копай Нео, копай -- летать научишься. © Matrix. Парадоксы
Re[5]: Preobrozovanie char
От: sergey_shandar США http://getboost.codeplex.com/
Дата: 19.03.04 02:29
Оценка: 1 (1)
Здравствуйте, Шахтер, Вы писали:

Ш>Да уж куда проще -- ездить из Москвы в Питер через Вашингтон.


Тут скорее другая аналогия, когда я звоню из Москвы в Питер, мне до лампочки как идет сигнал, хоть через Куала Лумпур (что вполне возможно).
Если знаешь чем плох lexical_cast, и как его можно исправить, и это действительно критично, люди работающие над boost всегда готовы выслушать дельные предложения.

А пугать людей магическими цифрами типа 32 (в char buf[32]) это хорошо? Почему 32, а не 128 или 13?

Но это больше к философии. Извинте, если что не так.
getboost.codeplex.com
citylizard.codeplex.com
Re[5]: Preobrozovanie char
От: ArtDenis Россия  
Дата: 19.03.04 04:29
Оценка:
Hello, Шахтер!
You wrote on Fri, 19 Mar 2004 01:41:21 GMT:

Ш> Да уж куда проще -- ездить из Москвы в Питер через Вашингтон.


Ш> Пересадка первая. lexical_cast -> detail::lexical_stream

Ш>...

Да уж, постарались ребята, так постарались . Меня мучает вот такой вопрос: если бы программисты, писавшие boost::lexical_cast сделали его попроще, смог бы он попасть в библиотеку boost ?
Posted via RSDN NNTP Server 1.8 beta
[ 🎯 Дартс-лига Уфы | 🌙 Программа для сложения астрофото ]
Re[6]: Preobrozovanie char
От: sergey_shandar США http://getboost.codeplex.com/
Дата: 19.03.04 05:10
Оценка: +2
Здравствуйте, ArtDenis, Вы писали:

AD>Да уж, постарались ребята, так постарались . Меня мучает вот такой вопрос: если бы программисты, писавшие boost::lexical_cast сделали его попроще, смог бы он попасть в библиотеку boost ?


Честно скажу, я не разбирался в деталях. Но, если есть реализация попроще, скорее всего попала бы в boost (why not?). Только сначала в черновики, потом бы выяснилось что она на некоторых платформах или с некоторыми вариантами опций компилятора не работает, или работает не корректно. Пришлось бы изменить код, подправить, и скорее всего, через некоторое время, получили бы такой же по сложности код То что там такое нагромождение, этому наверняка есть какое то обоснование. Возможно, учитываеться многопоточноснь, обработка исключений, отладочные функции, разрядность, ошибки и нюансы разных компиляторов и библиотек (обхода таких "нюансов" хватает в boost), и т.п.. В отличии от Шахтера, я не думаю что boost пишут не программисты.

IMHO, Основная идея boost ведь не в том что бы внутри код был предельно простым, а что бы этой библиотекой можно было пользовать на разных платформах, не переписывая по сто раз велосипеды, например, того же преобразования вещественного числа в строку.
getboost.codeplex.com
citylizard.codeplex.com
Re[6]: Preobrozovanie char
От: c-smile Канада http://terrainformatica.com
Дата: 19.03.04 05:44
Оценка: +2
Здравствуйте, sergey_shandar, Вы писали:

_>А пугать людей магическими цифрами типа 32 (в char buf[32]) это хорошо? Почему 32, а не 128 или 13?


char *  gcvt ( double value, int num, char * buffer );


In total, depending on the implementation, buffer should be between 8 and 9 characters larger than num to contain any possible result.

http://www.cplusplus.com/ref/cstdlib/gcvt.html

И по поводу философии замолвлю слово:
boost::lexical_cast скорее ближе к философии VB/Java/C# чем к C++.

И по поводу практики замолвлю слово:
boost::lexical_cast будет аллоцировать строку на каждое преобразование. Это хорошо?

И последнее: судя по уровню человека задающего вопрос ему только буста и не хватает для полного щастья.
Re[6]: Preobrozovanie char
От: Шахтер Интернет  
Дата: 19.03.04 05:53
Оценка: :)))
Здравствуйте, ArtDenis, Вы писали:

AD>Hello, Шахтер!

AD>You wrote on Fri, 19 Mar 2004 01:41:21 GMT:

Ш>> Да уж куда проще -- ездить из Москвы в Питер через Вашингтон.


Ш>> Пересадка первая. lexical_cast -> detail::lexical_stream

Ш>>...

AD>Да уж, постарались ребята, так постарались . Меня мучает вот такой вопрос: если бы программисты, писавшие boost::lexical_cast сделали его попроще, смог бы он попасть в библиотеку boost ?


Да ни в жисть.
... << RSDN@Home 1.1.0 stable >>
В XXI век с CCore.
Копай Нео, копай -- летать научишься. © Matrix. Парадоксы
Re[7]: Preobrozovanie char
От: ArtDenis Россия  
Дата: 19.03.04 05:54
Оценка:
Hello, sergey_shandar!
You wrote on Fri, 19 Mar 2004 05:10:00 GMT:

ss> IMHO, Основная идея boost ведь не в том что бы внутри код был предельно

ss> простым, а что бы этой библиотекой можно было пользовать на разных
ss> платформах, не переписывая по сто раз велосипеды, например, того же
ss> преобразования вещественного числа в строку.

Да, ладно, я же просто пошутил. А если говорить серьёзно, то мне не понятно, почему в C++ и C нет средства для преобразования чисел в строковое представление, которое бы удовлетворяло следующим условиям:

1. Безопасность и надёжность
2. Выбор формата чисел
3. Высокая скорость
4. Маленький объём кода

Если построить таблицу по функциям переводящим double -> text и по вышеприведённым условиям, то получим:

Средство            |  1    2    3    4
====================+=====================
sprintf             |  -    +    +    +
------------------------------------------
gcvt, ecvt, fcvt    |  -    -    +    +
------------------------------------------
stringstream        |  +    +    -    -
------------------------------------------
boost::lexical_cast |  +    -    -    - 
------------------------------------------


Как видно, четырёх плюсов подряд нигде не наблюдаеся

---
СНП Артёмов Денис. E-mail: artden(на)ufacom(точка)ru
Posted via RSDN NNTP Server 1.8 beta
[ 🎯 Дартс-лига Уфы | 🌙 Программа для сложения астрофото ]
Re[6]: Preobrozovanie char
От: Шахтер Интернет  
Дата: 19.03.04 06:01
Оценка:
Здравствуйте, sergey_shandar, Вы писали:

_>Здравствуйте, Шахтер, Вы писали:


Ш>>Да уж куда проще -- ездить из Москвы в Питер через Вашингтон.


_>Тут скорее другая аналогия, когда я звоню из Москвы в Питер, мне до лампочки как идет сигнал, хоть через Куала Лумпур (что вполне возможно).


Если у тебя задержка сигнала будет 10 секунд, разговаривать нормально ты не сможешь.

_>Если знаешь чем плох lexical_cast, и как его можно исправить, и это действительно критично, люди работающие над boost всегда готовы выслушать дельные предложения.


Скажем так, я не работаю бесплатно.

_>А пугать людей магическими цифрами типа 32 (в char buf[32]) это хорошо?


Вот это пугало зарыто в недрах stl: _MAX_EXP_DIG + _MAX_SIG_DIG + 64.

_>Почему 32, а не 128 или 13?


Баг стандарта. Приходится исправлять вручную. Сильно умные небожители, пишущие стандарт, никак не могут заметиь простых человеческих нужд -- а именно примитивов преобразования фундаментальных типов в строку ( типа itoa , _gcvt и.т.п. ). Вот в соответствующем заголовке и должны быть представлены соответствующие константы для размеров буферов. Написать соответсвующиё хидер -- делов на 10 минут. Рассмотреть и утвердить это в комитете не могут уже много лет. Очевидно, у ключевых членов комитета, большие задержки в сигнальных цепях в голове.

_>Но это больше к философии. Извинте, если что не так.


Это не философия, а практика. Если я в своей работе буду применять такие тормознутые средства, то у тебя действительно задержка сигнала от Москвы до Питера будет 10 секунд.
... << RSDN@Home 1.1.0 stable >>
В XXI век с CCore.
Копай Нео, копай -- летать научишься. © Matrix. Парадоксы
Re[7]: Preobrozovanie char
От: sergey_shandar США http://getboost.codeplex.com/
Дата: 19.03.04 06:11
Оценка: 1 (1)
Здравствуйте, c-smile, Вы писали:

CS>И последнее: судя по уровню человека задающего вопрос ему только буста и не хватает для полного щастья.


Тогда уж скорее ему не хватает вот этого, для полного примера :

CS>In total, depending on the implementation, buffer should be between 8 and 9 characters larger than num to contain any possible result.

CS>http://www.cplusplus.com/ref/cstdlib/gcvt.html

И еще два параграфа по подсчету еще одного магического числа 'num'.

Вот именно, исходя из того, что человеку просто нужно преобразовать число в строку, boost ему и не хватает. Хотя я ничего против других вариантов не имею. Пусть выбирает. Причем, скорее всего, он/она выберет вариант Кодта.
getboost.codeplex.com
citylizard.codeplex.com
Re[7]: Preobrozovanie char
От: sergey_shandar США http://getboost.codeplex.com/
Дата: 19.03.04 06:25
Оценка:
Здравствуйте, Шахтер, Вы писали:

Ш>Вот это пугало зарыто в недрах stl: _MAX_EXP_DIG + _MAX_SIG_DIG + 64.

Ш>Баг стандарта. Приходится исправлять вручную. ...
Если так, то зачем тогда советовать людям то что проблематично использовать?

Ш>Это не философия, а практика. Если я в своей работе буду применять такие тормознутые средства..., то у тебя действительно задержка сигнала от Москвы до Питера будет 10 секунд.

А он может СМС посылает (опять аналогии , я не видел что бы в вопросе были слова сверх быстрое преобразования числа в строку.
Многие приложения на Java работают, и ниче, не тормозят, даже на мобильных телефонах. А когда тормозят то те функции которые тормозят и переписываються.
getboost.codeplex.com
citylizard.codeplex.com
Re[3]: Preobrozovanie char
От: Пупырь Ниоткуда  
Дата: 19.03.04 07:23
Оценка:
A>>Смотри в сторону boost::lexical_cast
К>Будьте проще, и люди потянутся.
К>
К>char buf[32]; // вроде должно хватить
К>sprintf(buf, "%g", 1.23); // %g - выбирать наиболее подходящую запись: 0.123e+0001 или 1.23
К>

Вот и выросло поколение программистов не знающих sprintf
... << RSDN@Home 1.1.3 beta 1 >>
Re[4]: Preobrozovanie char
От: alexkro  
Дата: 19.03.04 08:31
Оценка: 1 (1) -2 :))
Здравствуйте, Пупырь, Вы писали:

П>Вот и выросло поколение программистов не знающих sprintf


И слава Богу! Теперь будем ждать когда вымрет поколение, которое не может увидеть, что есть что-то кроме sprintf.
Re: Preobrozovanie char
От: Libra Россия  
Дата: 19.03.04 09:16
Оценка:
Здравствуйте, Аноним, Вы писали:

А>|Privet all.

А>||Kak preobrozovat char[] v float, to est esli imeem float 0.4 poluchit char[] "0.4".
А>\Spasibo

char buf[BUF_SIZE];
float f = 0.4;
sprintf(buf, "%f", f);
Species come and go, but the earth stands forever fast...
Re[8]: Preobrozovanie char
От: folk Россия  
Дата: 20.03.04 05:34
Оценка:
Здравствуйте, ArtDenis, Вы писали:

AD>Да, ладно, я же просто пошутил. А если говорить серьёзно, то мне не понятно, почему в C++ и C нет средства для преобразования чисел в строковое представление, которое бы удовлетворяло следующим условиям:


AD>1. Безопасность и надёжность

AD>2. Выбор формата чисел
AD>3. Высокая скорость
AD>4. Маленький объём кода

AD>Если построить таблицу по функциям переводящим double -> text и по вышеприведённым условиям, то получим:


AD>
AD>Средство            |  1    2    3    4
AD>====================+=====================
AD>sprintf             |  -    +    +    +
AD>------------------------------------------
AD>gcvt, ecvt, fcvt    |  -    -    +    +
AD>------------------------------------------
AD>stringstream        |  +    +    -    -
AD>------------------------------------------
AD>boost::lexical_cast |  +    -    -    - 
AD>------------------------------------------
AD>


AD>Как видно, четырёх плюсов подряд нигде не наблюдаеся


Я тоже как-то думал над этим. И тоже пришел к выводу что в стандартных C/C++ нет удобного способа пребразования значения в строковое представление. А альтернативные удобные способы достаточно дорогие.

Мне хочется иметь набор перегруженных шаблонов функций, возвращающих итератор на конец строкового представления, конечно же без зачастую ненужного нуль-терминирования. Все параметры форматирования должны паковаться в спец тип вместе с форматируемым значением.
Типа такого на примере signed/unsigned int и дополнительного шестнацатиричного формата:

// шестнадцатиричный форматтер - может использоваться с любыми семантически подходящими типами
template<typename T>
struct hex_t
{
  T value;
  explicit hex_t(T val): value(val) {}
};

template<typename T>
hex_t<T> hex(T const& val) { return hex_t<T>(val); }

// объявления шаблонов преобразования
tempalte<typename OutIt>
OutIt stringize(OutIt it, unsigned x);

tempalte<typename OutIt>
OutIt stringize(OutIt it, signed x);

tempalte<typename OutIt>
OutIt stringize(OutIt it, hex_t<unsigned> x);

tempalte<typename OutIt>
OutIt stringize(OutIt it, hex_t<signed> x);

// здесь мы несколько выбиваемся из стиля, но должнен же быть шаблон для удобной работы с массивом символов,
// терминирующий нулем и возвращающий указатель на НАЧАЛО массива
template<typename Char, typename T>
Char* stringize_to_array(Char* buf, T const& x)
{
  *stringize(buf, x) = 0;
  return buf;
}


Такие шаблоны было бы весьма удобно использовать в различных ситуациях. Вот напридумывал примеры использования:

void test()
{
  std::string s;
  stringize(std::back_inserter(s), hex(12345));

  stringize(std::ostreambuf_iterator<wchar_t>(std::wcout), 12345);

  char buf[32];
  std::cout << stringize_to_array(buf, 12345);
}


ЗЫ Для целых чисел это сделать совсем несложно, да и вариантов формата для них немного. А вот с плавающими числами все сложнее.
На самом деле, люди не читают газеты, они принимают их каждое утро, так же как ванну. ©Маршалл Мак-Льюэн
Re: Preobrozovanie char
От: marat321  
Дата: 20.10.05 08:50
Оценка:
Здравствуйте, <Аноним>, Вы писали:

Почему нельзя использовать std::string и в нее писать через потоки, а потом выдрать указатель на char?
... << RSDN@Home 1.1.4 stable SR1 rev. 568>>
Re[5]: Preobrozovanie char
От: Pavel Chikulaev Россия  
Дата: 21.10.05 08:37
Оценка:
Здравствуйте, Шахтер, Вы писали:

Ш>Не надо путать программирование и идиотию. Авторы boost а, во всяком случае этой его части, программистами названы быть не могут. Ими вообще должны заниматься специальные люди в былых халатах.


Кстати велика вероятность, что boost::lexical_cast будет в C++0x. Так что привыкай.
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.