xlocmon
来自「C语言库函数的原型,有用的拿去」· 代码 · 共 972 行 · 第 1/2 页
TXT
972 行
; // assume no sign
else if (0 < (_Ppunct_fac->positive_sign()).size()
&& _Ppunct_fac->positive_sign()[0] == *_First)
{ // match positive sign
++_First;
_Sign = _Ppunct_fac->positive_sign();
}
else if (0 < (_Ppunct_fac->negative_sign()).size()
&& _Ppunct_fac->negative_sign()[0] == *_First)
{ // match negative sign
++_First;
_Sign = _Ppunct_fac->negative_sign();
_Neg = true;
}
else if (0 == (_Ppunct_fac->positive_sign()).size())
;
else if (0 == (_Ppunct_fac->negative_sign()).size())
_Neg = true;
break; // sign match can't fail
case money_base::value:
{ // parse value field
int _Fracdigseen = 0;
int _Fracdigits = _Ppunct_fac->frac_digits();
const _Elem _E0 = _MAKLOCCHR(_Elem, '0', _Cvt);
const string _Grouping = _Ppunct_fac->grouping();
const _Elem _Kseparator = _Grouping.size() == 0
? (_Elem)0 : _Ppunct_fac->thousands_sep();
if (_Kseparator == (_Elem)0
|| CHAR_MAX <= (unsigned char)*_Grouping.c_str())
for (; _First != _Last
&& _E0 <= *_First && *_First <= _E0 + 9; ++_First)
_Val += *_First; // no grouping, just gather digits
else
{ // grouping specified, gather digits and group sizes
string _Groups((size_t)1, '\0');
size_t _Group = 0;
for (; _First != _Last; ++_First)
if ( _E0 <= *_First && *_First <= _E0 + 9)
{ // got a digit, add to group size
_Val += *_First;
if (_Groups[_Group] != CHAR_MAX)
++_Groups[_Group];
}
else if (_Groups[_Group] == '\0'
|| *_First != _Kseparator)
break; // not a group separator, done
else
{ // add a new group to _Groups string
_Groups.append((size_t)1, '\0');
++_Group;
}
if (_Group == 0)
; // no thousands separators seen
else if ('\0' < _Groups[_Group])
++_Group; // add trailing group to group count
else
_Bad = true; // trailing separator, fail
for (const char *_Pg = _Grouping.c_str();
!_Bad && 0 < _Group; )
if (*_Pg == CHAR_MAX)
break; // end of grouping constraints to check
else if (0 < --_Group && *_Pg != _Groups[_Group]
|| 0 == _Group && *_Pg < _Groups[_Group])
_Bad = true; // bad group size, fail
else if ('\0' < _Pg[1])
++_Pg; // group size okay, advance to next test
if (_Bad)
break; // bad grouping, give up
}
const _Elem _Point = _Ppunct_fac->decimal_point();
if (_First != _Last
&& _Point != (_Elem)0
&& *_First == _Point)
{ // seen decimal point, gather fraction digits
while (++_First != _Last
&& _Fracdigseen < _Fracdigits
&& _E0 <= *_First && *_First <= _E0 + 9)
_Val += *_First, ++_Fracdigseen;
if (_Fracdigseen < _Fracdigits)
_Bad = true; // short fraction
}
if (_Val.size() == 0)
_Bad = true; // fail if no elements parsed
else
for (; _Fracdigseen < _Fracdigits; ++_Fracdigseen)
_Val += _E0; // pad out fraction
break;
}
case money_base::space:
case money_base::none:
{ // parse optional space
if (_Off == 3)
break; // ignore space at end
const ctype<_Elem>& _Ctype_fac =
_USE(_Iosbase.getloc(), ctype<_Elem>);
while (_First != _Last
&& _Ctype_fac.is(ctype_base::space, *_First))
++_First; // skip any space
}
}
if (!_Bad && 1 < _Sign.size())
{ // match rest of sign string
typename string_type::const_iterator _Source;
for (_Source = _Sign.begin(); ++_Source != _Sign.end()
&& _First != _Last && *_First == *_Source; ++_First)
;
if (_Source != _Sign.end())
_Bad = true; // rest of sign doesn't match, fail
}
if (_Bad)
_Val.erase(); // bad input, return empty string
else if (_Neg)
_Val.insert((size_t)0, (size_t)1, _MAKLOCCHR(_Elem, '-', _Cvt));
return (_Val);
}
_Locinfo::_Cvtvec _Cvt; // conversion information
};
// STATIC money_get::id OBJECT
template<class _Elem,
class _InIt>
__PURE_APPDOMAIN_GLOBAL locale::id money_get<_Elem, _InIt>::id;
// TEMPLATE CLASS money_put
template<class _Elem,
class _OutIt = ostreambuf_iterator<_Elem, char_traits<_Elem> > >
class money_put
: public locale::facet
{ // facet for converting encoded monetary amounts to text
typedef moneypunct<_Elem, false> _Mypunct0;
typedef moneypunct<_Elem, true> _Mypunct1;
public:
typedef _Elem char_type;
typedef _OutIt iter_type;
typedef basic_string<_Elem, char_traits<_Elem>, allocator<_Elem> >
string_type;
_OutIt put(_OutIt _Dest,
bool _Intl, ios_base& _Iosbase, _Elem _Fill,
long double _Val) const
{ // put long double to _Dest
return (do_put(_Dest, _Intl, _Iosbase, _Fill, _Val));
}
_OutIt put(_OutIt _Dest,
bool _Intl, ios_base& _Iosbase, _Elem _Fill,
const string_type& _Val) const
{ // put string_type to _Dest
return (do_put(_Dest, _Intl, _Iosbase, _Fill, _Val));
}
__PURE_APPDOMAIN_GLOBAL _CRTIMP2_PURE static locale::id id; // unique facet id
explicit money_put(size_t _Refs = 0)
: locale::facet(_Refs)
{ // construct from current locale
_BEGIN_LOCINFO(_Lobj)
_Init(_Lobj);
_END_LOCINFO()
}
money_put(const _Locinfo& _Lobj, size_t _Refs = 0)
: locale::facet(_Refs)
{ // construct from specified locale
_Init(_Lobj);
}
static size_t _Getcat(const locale::facet **_Ppf = 0,
const locale *_Ploc = 0)
{ // return locale category mask and construct standard facet
if (_Ppf != 0 && *_Ppf == 0)
*_Ppf = _NEW_CRT money_put<_Elem, _OutIt>(
_Locinfo(_Ploc->c_str()));
return (_X_MONETARY);
}
protected:
virtual __CLR_OR_THIS_CALL ~money_put()
{ // destroy the object
}
void _Init(const _Locinfo& _Lobj)
{ // initialize from _Locinfo object
_Cvt = _Lobj._Getcvt();
}
virtual _OutIt __CLR_OR_THIS_CALL do_put(_OutIt _Dest,
bool _Intl, ios_base& _Iosbase, _Elem _Fill,
long double _Val) const
{ // put long double to _Dest
bool _Negative = false;
if (_Val < 0)
_Negative = true, _Val = -_Val;
size_t _Exp;
for (_Exp = 0; 1e35 <= _Val && _Exp < 5000; _Exp += 10)
_Val /= 1e10; // drop 10 zeros before decimal point
string_type _Val2;
char _Buf[40];
int _Count = _CSTD sprintf_s(_Buf, sizeof (_Buf), "%.0Lf",
_Val); // convert to chars
for (int _Off = 0; _Off < _Count; ++_Off)
_Val2.append((typename string_type::size_type)1,
_MAKLOCCHR(_Elem, _Buf[_Off], _Cvt)); // convert chars
_Val2.append(_Exp,
_MAKLOCCHR(_Elem, '0', _Cvt)); // scale by trailing zeros
return (_Putmfld(_Dest, _Intl, _Iosbase, _Fill, _Negative, _Val2));
}
virtual _OutIt __CLR_OR_THIS_CALL do_put(_OutIt _Dest,
bool _Intl, ios_base& _Iosbase, _Elem _Fill,
const string_type& _Val) const
{ // put string_type to _Dest
const _Elem _E0 = _MAKLOCCHR(_Elem, '0', _Cvt);
const _Elem *_Ptr = _Val.c_str();
bool _Negative = false;
if (*_Ptr == _MAKLOCCHR(_Elem, '-', _Cvt))
_Negative = true, ++_Ptr;
size_t _Count;
for (_Count = 0; _E0 <= _Ptr[_Count] && _Ptr[_Count] <= _E0 + 9;
++_Count)
; // count digits
string_type _Val2(_Ptr, _Count);
if (_Count == 0) // replace empty digit string with '0'
_Val2.append((typename string_type::size_type)1, _E0);
return (_Putmfld(_Dest, _Intl, _Iosbase, _Fill, _Negative, _Val2));
}
private:
_OutIt _Putmfld(_OutIt _Dest,
bool _Intl, ios_base& _Iosbase, _Elem _Fill,
bool _Neg, string_type _Val) const
{ // put string_type with just digits to _Dest
_DEBUG_POINTER(_Dest);
const _Mpunct<_Elem> *_Ppunct_fac;
if (_Intl)
_Ppunct_fac =
&_USE(_Iosbase.getloc(), _Mypunct1); // international
else
_Ppunct_fac =
&_USE(_Iosbase.getloc(), _Mypunct0); // local
const _Elem _E0 = _MAKLOCCHR(_Elem, '0', _Cvt);
const string _Grouping = _Ppunct_fac->grouping();
int _Ifracdigits = _Ppunct_fac->frac_digits();
unsigned int _Fracdigits = _Ifracdigits < 0 ? -_Ifracdigits
: _Ifracdigits;
if (_Val.size() <= _Fracdigits)
_Val.insert((size_t)0, _Fracdigits - _Val.size() + 1, _E0);
else if (*_Grouping.c_str() != CHAR_MAX && '\0' < *_Grouping.c_str())
{ // grouping specified, add thousands separators
const _Elem _Kseparator = _Ppunct_fac->thousands_sep();
const char *_Pg = _Grouping.c_str();
size_t _Off = _Val.size() - _Fracdigits; // start of fraction
while (*_Pg != CHAR_MAX && '\0' < *_Pg
&& (size_t)*_Pg < _Off)
{ // add a thousands separator, right to left
_Val.insert(_Off -= *_Pg, (size_t)1, _Kseparator);
if ('\0' < _Pg[1])
++_Pg; // not last group, advance
}
}
money_base::pattern _Pattern;
string_type _Sign;
if (_Neg)
{ // negative value, choose appropriate format and sign
_Pattern = _Ppunct_fac->neg_format();
_Sign = _Ppunct_fac->negative_sign();
}
else
{ // positive value, choose appropriate format and sign
_Pattern = _Ppunct_fac->pos_format();
_Sign = _Ppunct_fac->positive_sign();
}
string_type _Symbol;
if (_Iosbase.flags() & ios_base::showbase)
_Symbol = _Ppunct_fac->curr_symbol(); // showbase ==> show $
bool _Intern = false;
size_t _Fillcount, _Off;
for (_Fillcount = 0, _Off = 0; _Off < 4; ++_Off)
switch (_Pattern.field[_Off])
{ // accumulate total length in _Fillcount
case money_base::symbol: // count currency symbol size
_Fillcount += _Symbol.size();
break;
case money_base::sign: // count sign size
_Fillcount += _Sign.size();
break;
case money_base::value: // count value field size
_Fillcount += _Val.size() + (0 < _Fracdigits ? 1 : 0)
+ (_Val.size() <= _Fracdigits
? _Fracdigits - _Val.size() + 1 : 0);
break;
case money_base::space: // count space size
++_Fillcount; // at least one space
// fall through
case money_base::none: // count space size
if (_Off != 3)
_Intern = true; // optional internal fill
break;
}
_Fillcount = _Iosbase.width() <= 0
|| (size_t)_Iosbase.width() <= _Fillcount
? 0 : (size_t)_Iosbase.width() - _Fillcount;
ios_base::fmtflags _Afl =
_Iosbase.flags() & ios_base::adjustfield;
if (_Afl != ios_base::left
&& (_Afl != ios_base::internal || !_Intern))
{ // put leading fill
_Dest = _Rep(_Dest, _Fill, _Fillcount);
_Fillcount = 0;
}
for (_Off = 0; _Off < 4; ++_Off)
switch (_Pattern.field[_Off])
{ // put components as specified by _Pattern
case money_base::symbol: // put currency symbol
_Dest = _Put(_Dest, _Symbol.begin(), _Symbol.size());
break;
case money_base::sign: // put sign
if (0 < _Sign.size())
_Dest = _Put(_Dest, _Sign.begin(), 1);
break;
case money_base::value: // put value field
if (_Fracdigits == 0)
_Dest = _Put(_Dest, _Val.begin(),
_Val.size()); // no fraction part
else if (_Val.size() <= _Fracdigits)
{ // put leading zero, all fraction digits
*_Dest++ = _E0;
*_Dest++ = _Ppunct_fac->decimal_point();
_Dest = _Rep(_Dest, _E0,
_Fracdigits - _Val.size()); // insert zeros
_Dest = _Put(_Dest, _Val.begin(), _Val.size());
}
else
{ // put both integer and fraction parts
_Dest = _Put(_Dest, _Val.begin(),
_Val.size() - _Fracdigits); // put integer part
*_Dest++ = _Ppunct_fac->decimal_point();
_Dest = _Put(_Dest, _Val.end() - _Fracdigits,
_Fracdigits); // put fraction part
}
break;
case money_base::space: // put any internal fill
_Dest = _Rep(_Dest, _Fill, 1);
// fall through
case money_base::none: // put any internal fill
if (_Afl == ios_base::internal)
{ // put internal fill
_Dest = _Rep(_Dest, _Fill, _Fillcount);
_Fillcount = 0;
}
}
if (1 < _Sign.size())
_Dest = _Put(_Dest, _Sign.begin() + 1,
_Sign.size() - 1); // put remainder of sign
_Iosbase.width(0);
return (_Rep(_Dest, _Fill, _Fillcount)); // put trailing fill
}
static _OutIt _Put(_OutIt _Dest,
typename string_type::const_iterator _Source, size_t _Count)
{ // put [_Source, _Source + _Count) to _Dest
for (; 0 < _Count; --_Count, ++_Dest, ++_Source)
*_Dest = *_Source;
return (_Dest);
}
static _OutIt _Rep(_OutIt _Dest,
_Elem _Ch, size_t _Count)
{ // put _Count * _Ch to _Dest
for (; 0 < _Count; --_Count, ++_Dest)
*_Dest = _Ch;
return (_Dest);
}
_Locinfo::_Cvtvec _Cvt; // conversion information
};
// STATIC money_put::id OBJECT
template<class _Elem,
class _OutIt>
__PURE_APPDOMAIN_GLOBAL locale::id money_put<_Elem, _OutIt>::id;
#if defined(_DLL_CPPLIB) && !defined(_M_CEE_PURE)
#ifdef __FORCE_INSTANCE
template _PGLOBAL const bool moneypunct<char, true>::intl;
template _PGLOBAL const bool moneypunct<char, false>::intl;
template __PURE_APPDOMAIN_GLOBAL locale::id
moneypunct<char, true>::id;
template __PURE_APPDOMAIN_GLOBAL locale::id
moneypunct<char, false>::id;
template __PURE_APPDOMAIN_GLOBAL locale::id
money_get<char, istreambuf_iterator<char,
char_traits<char> > >::id;
template __PURE_APPDOMAIN_GLOBAL locale::id
money_put<char, ostreambuf_iterator<char,
char_traits<char> > >::id;
template _PGLOBAL const bool moneypunct<wchar_t, true>::intl;
template _PGLOBAL const bool moneypunct<wchar_t, false>::intl;
template __PURE_APPDOMAIN_GLOBAL locale::id
moneypunct<wchar_t, true>::id;
template __PURE_APPDOMAIN_GLOBAL locale::id
moneypunct<wchar_t, false>::id;
template __PURE_APPDOMAIN_GLOBAL locale::id
money_get<wchar_t, istreambuf_iterator<wchar_t,
char_traits<wchar_t> > >::id;
template __PURE_APPDOMAIN_GLOBAL locale::id
money_put<wchar_t, ostreambuf_iterator<wchar_t,
char_traits<wchar_t> > >::id;
#ifdef _CRTBLD_NATIVE_WCHAR_T
template _PGLOBAL const bool moneypunct<unsigned short, true>::intl;
template _PGLOBAL const bool moneypunct<unsigned short, false>::intl;
template __PURE_APPDOMAIN_GLOBAL locale::id
moneypunct<unsigned short, true>::id;
template __PURE_APPDOMAIN_GLOBAL locale::id
moneypunct<unsigned short, false>::id;
template __PURE_APPDOMAIN_GLOBAL locale::id
money_get<unsigned short, istreambuf_iterator<unsigned short,
char_traits<unsigned short> > >::id;
template __PURE_APPDOMAIN_GLOBAL locale::id
money_put<unsigned short, ostreambuf_iterator<unsigned short,
char_traits<unsigned short> > >::id;
#endif /* _CRTBLD_NATIVE_WCHAR_T */
#endif /* __FORCE_INSTANCE */
#endif /* defined(_DLL_CPPLIB) etc. */
_STD_END
#pragma pop_macro("new")
#pragma warning(pop)
#pragma pack(pop)
#endif /* RC_INVOKED */
#endif /* _XLOCMON_ */
/*
* Copyright (c) 1992-2009 by P.J. Plauger. ALL RIGHTS RESERVED.
* Consult your license regarding permissions and restrictions.
V5.20:0009 */
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?