首页 理论教育 C++STL精解:数值类locale

C++STL精解:数值类locale

时间:2023-10-25 理论教育 版权反馈
【摘要】:虚函数主要用于几种数值类型,实施过程中会将较小类型处理为较大的类型。这些实例化类涉及了ios_base&类型的参数,可用于格式化特例和与它相应的locale类。2)阶段2收集的字符序列会引起扫描,并汇报输入错误,之后ios_base::failbit被设置给变量err。假定当前的locale对象属于“C”类型locale。其值被get-loc()函数返回。表12-13 整型数值转换字符型对于浮点类型的转换,函数会判断浮点转换符标识,见表12-14。表12-16 数值转换为转换一个浮点类型,如果!

C++STL精解:数值类locale

类num_get< >和类num_put< >处理数值格式和数值分解。虚函数主要用于几种数值类型,实施过程中会将较小类型处理为较大的类型。所有特例化的成员函数仅仅应用于实例化类。这些实例化类可以是num_get<char>、num_get<wchar_t>、num_get<C,InputItera-tor>、num_put<char>、num_put<wchar_t>和num_put<C,OutputIterator>。这些实例化类涉及了ios_base&类型的参数,可用于格式化特例和与它相应的locale类。刻面numpunct< >用于识别所有数值类标点优先,同时刻面ctype< >用于字符分类。

对于标准流的抽出器和插入器成员,使用num_get< >和num_put< >成员函数格式化或分解数值。

1.模板类num_get

978-7-111-51399-5-Chapter12-104.jpg

978-7-111-51399-5-Chapter12-105.jpg

刻面num_get< >用于分解输入序列中的数值数据。

模板类num_get< >包含了部分普通成员get()函数,还包含了一部分虚do_get()函数。虚do_get()函数可实现从输入流in中读取字符,并按照str.flag()阐释这些字符,使用刻面use_facet<ctype<chart>>(loc)和use_facet<numpunct<charT>>(loc)。此处loc是str.getloc()的返回值,如果产生错误,val是不变的,否则其将被设置为结果数值。参数的运行细节如下。

阶段1:判断一个特殊的转换。

阶段2:从输入流in中读取字符,并判断相应的字符值。

阶段3:存储结果。

各阶段的细节如下。

阶段1:初始化本地变量

978-7-111-51399-5-Chapter12-106.jpg

对于转换整数类型inter,函数决定整形转换(见表12-11)。

12-11 整形转换

978-7-111-51399-5-Chapter12-107.jpg

若转换浮点类型,则使用标识符“%g”;若转换空指针(void∗),则需要使用标识符“%p”。如果需要,还可以使用长度调整标识符(见表12-12)。

12-12 长度调整标识符

978-7-111-51399-5-Chapter12-108.jpg

阶段2:如果in==end,第二阶段将终止。否则charT类型会从输入流in中抽取,并初始化给本地变量。

978-7-111-51399-5-Chapter12-109.jpg

值src和atoms被定义:

978-7-111-51399-5-Chapter12-110.jpg

若参数discard为true,则字符的位置需要被记忆;否则,字符可以被忽略。若参数dis-card为false,需要检查字符c是否被允许作为阶段1中符号转换的输入流in中的下一个字符。如果为真,该字符被收集。

如果字符被抛弃或被收集,输入流使用“++”可以前进,并进行处理,例如++in。

阶段3:阶段2的处理结果可能是以下两种。

1)在阶段2中,一个字符序列被收集,并被转换成该类型的值。该值被存储在val中,并且ios_base::goodbit被存储在变量err中。

2)阶段2收集的字符序列会引起扫描,并汇报输入错误,之后ios_base::failbit被设置给变量err。数字分组被检查,即抛弃分隔符的位置需要被检查,并和use_facet<numpunct<charT>>(loc).grouping()保持一致。如果它们不能保持一致,ios_base::failbit的值将被设置给err变量。

无论任何情况,如果阶段2的处理过程被条件(in==end)被终止,err|=ios_base::eofbit会随即被执行

978-7-111-51399-5-Chapter12-111.jpg

如果(str.flag()&&ios_base::boolalpha)==0,输入操作将继续,输入的值被存入布尔变量val中。接着需要对val的值进行判断:若被存储的值是0,则val的值为false;若被存储的值是1,则val的值为true。否则,语句err|=ios_ base::failbit被执行,并不存储任何值。

一旦目标序列被判断,似乎是通过调用刻面的falsename()函数和truename()函数。输入型迭代器in同end是可以相等的,此时in==end。当且仅当目标序列被单独匹配时,val的值会被设置给相应的值。[in,end]中的连续字符可以获取,在目标序列中并不按位置匹配。迭代器in总是指向成功匹配的最后一个元素之前的某个位置。若val被设置,则err被设置为str.goodbit的值;或被设置为str.eofbit的值,当寻找另一个匹配的字符时,可以发现(in==end)。如果val没有被设置,然后err被设置为str.failbit的值。如果函数执行失败的原因是(in==end),数值val没有被设置数值,str.failbit会被设置为1,或者将(str.failbit|str.eofbit)的值设置给err。

函数返回指针in。

2.模板类num_put

模板类num_put的声明形式如下:

978-7-111-51399-5-Chapter12-112.jpg

978-7-111-51399-5-Chapter12-113.jpg

刻面num_put用于将数值数据格式化为一个字符串序列(像一个输出流)。虚do_put()函数用于将字符写至序列out中,并格式化val。下述语句用以实现本地类对象变量的初始化:

978-7-111-51399-5-Chapter12-114.jpg

函数的运行细节发生时一般包括以下几个阶段。

阶段1:判断一个printf的转换符标识spec,并决定字符的输出。假定当前的locale对象属于“C”类型locale。

阶段2:调整表示方式。转换阶段1决定的每一个字符被称为宽字符型式。其值被get-loc()函数返回。

978-7-111-51399-5-Chapter12-115.jpg

阶段3:判断何处是无用的。

阶段4:插入序列至流out中。(www.xing528.com)

下面对上述阶段进行详细描述。

阶段1:阶段1的第一个行为是判断转换符标识。描述该判断的表使用下述本地变量。

978-7-111-51399-5-Chapter12-116.jpg

在阶段1中,所有使用的表均是有序的,即只有第一行的条件为true,后面的语句才能执行。对于从整型到字符型的转换,函数会判断整型转换符标识。详见表12-13。

12-13 整型数值转换字符型

978-7-111-51399-5-Chapter12-117.jpg

对于浮点类型的转换,函数会判断浮点转换符标识,见表12-14。

12-14 浮点类型转换字符型

978-7-111-51399-5-Chapter12-118.jpg

对于转换过程中添加数据长度的标志,函数会判断长度修饰符,见表12-15。

12-15 格式中的长度修饰符

978-7-111-51399-5-Chapter12-119.jpg

转换符具有以下可选择的预先附属资格。详见表12-16。

12-16 数值转换

978-7-111-51399-5-Chapter12-120.jpg

为转换一个浮点类型,如果(flags&fixed)!=0或str.precision()>0,那么str.precision()是指定的数值。对于空指针的转换,可以使用转换符%p。

阶段1最后的表达式包括char's。通过调用printf(s,val)可以打印该表达式。此处,s是有上述决定的转换符。

阶段2:除了十进制小数点(.)之外,使用刻面use_facet<ctype<chart>>(loc).widen(c),任何字符c均可被转换为一个charT。通过numpunct<charT>punct=use_facet<numpunct<charT>>(str.getloc()),本地变量punct可以被初始化。对于整型类型,punct.thousands_sep()字符可以被插入至序列中,其值由punct.do_grouping()函数获取。十进制小数点符号(.)可以使用punct.decimal_point()函数替换。

阶段3:本地变量可以被初始化。例如,

978-7-111-51399-5-Chapter12-121.jpg

任何位置的垫衬可以由表12-17确定。

12-17 填充垫衬

978-7-111-51399-5-Chapter12-122.jpg

如果str.width()非零,并且阶段2之后的序列中charT的数目小于str.width(),程序会自动添加填充字符至序列中,使序列的长度自动增至规定长度(str.width())。

阶段4:阶段3末尾形成的charT类型的序列通过以下代码输出其内容。

978-7-111-51399-5-Chapter12-123.jpg

函数put的使用方法:

978-7-111-51399-5-Chapter12-124.jpg

函数的作用:若(str.flags()&ios_base::boolalpha)==0,则以下语句被执行:

978-7-111-51399-5-Chapter12-125.jpg

否则,以下语句被执行,并且将诸多s中的字符插入至流out.out中。

978-7-111-51399-5-Chapter12-126.jpg

下面使用例12-8来说明数值类的使用方法。

例12-8

978-7-111-51399-5-Chapter12-127.jpg

978-7-111-51399-5-Chapter12-128.jpg

例12-8的执行结果为:

978-7-111-51399-5-Chapter12-129.jpg

下面使用例12-9来说明imbue()函数的使用方法。

例12-9

978-7-111-51399-5-Chapter12-130.jpg

例12-9的执行结果为:

978-7-111-51399-5-Chapter12-131.jpg

免责声明:以上内容源自网络,版权归原作者所有,如有侵犯您的原创版权请告知,我们将尽快删除相关内容。

我要反馈