本文共 4726 字,大约阅读时间需要 15 分钟。
转载自:
数值格式化在"数值的内部表示"和"相应的文本描述"之间进行转换。
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,否则返回指向无法被解析的第一个字符