C++之国际化(5) --- 数值格式化

转载自:http://hi.baidu.com/nicker2010/item/819f073233b33fcb1a9696eb

 

数值格式化在"数值的内部表示"和"相应的文本描述"之间进行转换。
IOStream操作符将相应的转换工作委托给locale::numeric类型中的facet完成。
numeric类型中的facet包括三个(参见C++之国际化(3)):
num_get<>()         处理数值输入(解析)
num_put<>()         处理数值输出
numpunct<>()        数值I/O中相关的标点符号

=============================================================================

首先介绍numpunct类。
numpunct类源码,来源于MSDN:
template<class E>
class numpunct : public locale::facet
{
public:
    typedef E char_type;
    typedef basic_string<E> string_type;
    explicit numpunct(size_t refs = 0);
    E decimal_point() const; //返回一个字符用来表示小数点
    E thousands_sep() const; //返回一个字符用来表示千位符号
    string grouping() const; //返回一个string表示千万符号的设置为止
    string_type truename() const; //true和false的文本表示
    string_type falsename() const;
    static locale::id id;
protected:
    ~numpunct();
    virtual E do_decimal_point() const;
    virtual E do_thousands_sep() const;
    virtual string do_grouping() const;
    virtual string_type do_truename() const;
    virtual string_type do_falsename() const;
    };
C++标准规定,numpunct<char>,numpunct<wchar_t>必须实现
所谓千位分隔符号,就是用来间隔数字便于阅读,如:
1,000,000
但是并不是所有地区都用逗号,也并不是所有地区都三个数字一组。
德国(用点号,他们的小数点是逗号):1.000.000
尼泊尔:10.00.000
当每一组的数字的个数不同时,grouping()返回的字符串就发生作用了。
从右侧起,索引i处的数值代表第i组的数字个数,索引从0开始。
若果字符中的字符数量小于群组数,则最后一个数量将被重复
如果要创建无限大组,则应使用numeric_limits<char>::max()的返回值
如果不分组,就给一个空字符串
串                           效果
{ 0 } 或 ""                  (the default for grouping())   1000000
{ 3, 0 } 或 "\3"             1,000,000
{ 3, 2, 3, 0 } 或 "\3\2\3"   10,00,000
{ 2, CHAR_MAX, 0 }           10000,00
注意直接使用数字是不对的,如‘2’对应的是数字50(ASCII码)

=============================================================================

num_put类:
template<class E, class OutIt = ostreambuf_iterator<E> >
class num_put : public locale::facet
{
public:
    typedef E char_type;
    typedef OutIt iter_type;
    explicit num_put(size_t refs = 0);
    iter_type put(iter_type next, ios_base& x, E fill, long val) const; ///输出long
    iter_type put(iter_type next, ios_base& x, E fill, unsigned long val) const;///输出unsigned long
    iter_type put(iter_type next, ios_base& x, E fill, double val) const;///...
    iter_type put(iter_type next, ios_base& x, E fill, long double val) const;
    iter_type put(iter_type next, ios_base& x, E fill, const void *val) const;
    iter_type put(iter_type next, ios_base& x, E fill, bool val) const;
    static locale::id id;
protected:
    ~num_put();
    virtual iter_type do_put(iter_type next, ios_base& x, E fill, long val) const;
    virtual iter_type do_put(iter_type next, ios_base& x, E fill, unsigned long val) const;
    virtual iter_type do_put(iter_type next, ios_base& x, E fill, double val) const;
    virtual iter_type do_put(iter_type next, ios_base& x, E fill, long double val) const;
    virtual iter_type do_put(iter_type next, ios_base& x, E fill, const void *val) const;
    virtual iter_type do_put(iter_type next, ios_base& x, E fill, bool val) const;
    };
有两个template参数:字符型别E和output迭代器OutIt(缺省为ostreambuf_iterator)
put函数运用型别为E的字符,在OutIt所指位置写出val的文本表达式。
确切格式由x的格式化标志确定,fill用来当填充字符
返回一个迭代器,指向最后一个被写出的字符的下一位置。

=============================================================================

num_get类:
template<class E, class InIt = istreambuf_iterator<E> >
    class num_get : public locale::facet {
public:
    typedef E char_type;
    typedef InIt iter_type;
    explicit num_get(size_t refs = 0);
    iter_type get(iter_type first, iter_type last, ios_base& x, ios_base::iostate& st, long& val) const; ///解析long
    iter_type get(iter_type first, iter_type last, ios_base& x, ios_base::iostate& st, unsigned long& val) const;
    iter_type get(iter_type first, iter_type last, ios_base& x, ios_base::iostate& st, double& val) const;
    iter_type get(iter_type first, iter_type last, ios_base& x, ios_base::iostate& st, long double& val) const;
    iter_type get(iter_type first, iter_type last, ios_base& x, ios_base::iostate& st, void *& val) const;
    iter_type get(iter_type first, iter_type last, ios_base& x, ios_base::iostate& st, bool& val) const;
    static locale::id id;
protected:
    ~num_get();
    virtual iter_type do_get(iter_type first, iter_type last, ios_base& x, ios_base::iostate& st, long& val) const;
    virtual iter_type do_get(iter_type first, iter_type last, ios_base& x, ios_base::iostate& st, unsigned long& val) const;
    virtual iter_type do_get(iter_type first, iter_type last, ios_base& x, ios_base::iostate& st, double& val) const;
    virtual iter_type do_get(iter_type first, iter_type last, ios_base& x, ios_base::iostate& st, long double& val) const;
    virtual iter_type do_get(iter_type first, iter_type last, ios_base& x, ios_base::iostate& st, void *& val) const;
    virtual iter_type do_get(iter_type first, iter_type last, ios_base& x, ios_base::iostate& st, bool& val) const;
    };
有两个template参数:字符型别E和input迭代器InIt(缺省为istreambuf_iterator)
get函数解析first和last之间的字符序列,得出一个对应类型的数值。
确切格式由x的格式化标志确定
如果解析失败,则将st设为iso_base::failbit
反之则设为iso_base::goodbit,并将解析结果放入val中
val的原值只有在解析成功后才被修改

如果全部字符序列都解析完毕,则返回last,否则返回指向无法被解析的第一个字符

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值