类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
刻面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:存储结果。
各阶段的细节如下。
对于转换整数类型inter,函数决定整形转换(见表12-11)。
表12-11 整形转换
若转换浮点类型,则使用标识符“%g”;若转换空指针(void∗),则需要使用标识符“%p”。如果需要,还可以使用长度调整标识符(见表12-12)。
表12-12 长度调整标识符
阶段2:如果in==end,第二阶段将终止。否则charT类型会从输入流in中抽取,并初始化给本地变量。
值src和atoms被定义:
若参数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会随即被执行。
如果(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的声明形式如下:
刻面num_put用于将数值数据格式化为一个字符串序列(像一个输出流)。虚do_put()函数用于将字符写至序列out中,并格式化val。下述语句用以实现本地类对象变量的初始化:
函数的运行细节发生时一般包括以下几个阶段。
阶段1:判断一个printf的转换符标识spec,并决定字符的输出。假定当前的locale对象属于“C”类型locale。
阶段2:调整表示方式。转换阶段1决定的每一个字符被称为宽字符型式。其值被get-loc()函数返回。
阶段3:判断何处是无用的。
阶段4:插入序列至流out中。(www.xing528.com)
下面对上述阶段进行详细描述。
阶段1:阶段1的第一个行为是判断转换符标识。描述该判断的表使用下述本地变量。
在阶段1中,所有使用的表均是有序的,即只有第一行的条件为true,后面的语句才能执行。对于从整型到字符型的转换,函数会判断整型转换符标识。详见表12-13。
表12-13 整型数值转换字符型
对于浮点类型的转换,函数会判断浮点转换符标识,见表12-14。
表12-14 浮点类型转换字符型
对于转换过程中添加数据长度的标志,函数会判断长度修饰符,见表12-15。
表12-15 格式中的长度修饰符
转换符具有以下可选择的预先附属资格。详见表12-16。
表12-16 数值转换
为转换一个浮点类型,如果(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:本地变量可以被初始化。例如,
任何位置的垫衬可以由表12-17确定。
表12-17 填充垫衬
如果str.width()非零,并且阶段2之后的序列中charT的数目小于str.width(),程序会自动添加填充字符至序列中,使序列的长度自动增至规定长度(str.width())。
阶段4:阶段3末尾形成的charT类型的序列通过以下代码输出其内容。
函数put的使用方法:
函数的作用:若(str.flags()&ios_base::boolalpha)==0,则以下语句被执行:
否则,以下语句被执行,并且将诸多s中的字符插入至流out.out中。
下面使用例12-8来说明数值类的使用方法。
例12-8
例12-8的执行结果为:
下面使用例12-9来说明imbue()函数的使用方法。
例12-9
例12-9的执行结果为:
免责声明:以上内容源自网络,版权归原作者所有,如有侵犯您的原创版权请告知,我们将尽快删除相关内容。