Здравствуйте, 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 >>