std::money_get<CharT,InputIt>::get, do_get

来自cppreference.com
< cpp‎ | locale‎ | money get
定义于头文件 <locale>
public:

iter_type get(iter_type beg, iter_type end, bool intl, std::ios_base& str,

              std::ios_base::iostate& err, long double& units) const;
(1)
iter_type get(iter_type beg, iter_type end, bool intl, std::ios_base& str,
              std::ios_base::iostate& err, string_type& digits) const;
(2)
protected:

virtual iter_type do_get(iter_type beg, iter_type end, bool intl, std::ios_base& str,

                         std::ios_base::iostate& err, long double& units) const;
(3)
virtual iter_type do_get(iter_type beg, iter_type end, bool intl, std::ios_base& str,
                         std::ios_base::iostate& err, string_type& digits) const;
(4)

剖析来自输入迭代器的货币值,并写结果到 long double 或 string 。

1-2) 公开成员函数,调用最终导出类的成员函数 do_get
3-4) 从输入迭代器 beg 读取字符,期待找到按照 str.getloc() 中感染的 std::ctype 平面(下称 ct )、 str.getloc() 中感染的 std::moneypunct<CharT, intl> 平面(下称 mp )及获得自 str.flags() 的流格式化标志所指定的规则格式化的货币值。

若输入迭代器 beg 在分析完成前变得等于 end ,则在 err 中一同设置 failbiteofbit 。若分析因另一原因失败,则在 err 中设置 failbit 。无论如何,都不在错误时修改输出参数( unitsdigits )。

若分析成功,则不更改 err ,并存储结果于 unitsdigits

此函数所用的格式化 pattern 始终为 mp.neg_format()

mp.grouping() 不容许千分隔符,则将首个遇到的分隔符当做错误,否则将它们当做可选的。

money_base::spacemoney_base::nonepattern 中的最后元素,则分析器不尝试在分析货币值的其他组分后消耗任何空白符。否则在 money_base::space 出现处消耗一或多个空白字符。

str.flags() 中设置了 showbase 标志,则要求通货符号或通货字符串,若未设置,则通货符号可选。

若在格式化模式的 money_base::sign 位置找到 mp.positive_sign()mp.negative_sign() 所返回的字符串的首字符,则消耗之,而在货币值的所有其他组分后期待并消耗剩余字符。若 mp.positive_sign()mp.negative_sign() 均为非空,则要求有符号并匹配这些字符串的首字符之一。若这些字符串之一为空,则符号为可选(而若符号不存在,则结果的符号对应空的字符串的符号)。若两个字符均为空,或拥有相同首字符,则将正号给予结果。若输出参数为 string ( digits )而结果为负,则存储值 ct.widen('-') 为结果的首字符。

如同按 digits 中出现的顺序释出并放置来自输入的数位,或将它们置于临时缓冲区 buf1 中(若需要则以 ct.widen() 加宽),再用下方式从该缓冲区构造 units 的值:

static const char src[] = "0123456789-";
CharT atoms[sizeof(src)];
ct.widen(src, src + sizeof(src) - 1, atoms);
for (int i = 0; i < n; ++i)
buf2[i] = src[find(atoms, atoms+sizeof(src), buf1[i]) - atoms];
buf2[n] = 0;
sscanf(buf2, "%Lf", &units);

(其中 n 是从输入释出并存储 buf1 的字符数,而 buf2 是另一充分大的字符缓冲区)

返回值

指向辨识为货币字符串输入的合法部分的末字符立即后一位置的迭代器。

注意

假定通货单位为通货的最小非小数单位:美国中为美分,日本中为日元。从而美国本地环境中的输入序列 "$1,056.23" 会令 units 为数字 105623.0 或令 digits 为字符串 "105623"

因为若 showbase 关闭则通货符号为可选,但要求整个多字符 negative_sign() ,故给定格式化模式 {sign, value, space, symbol} 、关闭的 showbase"-" 的 negative_sign ,字符串 "-1.23 €" 会分析为 -123 ,而令 "€" 在输入流上留待未消耗,但若 negative_sign 为 "()" , 则完全消耗字符串 "(1.23 €)"

I/O 操纵符 std::get_money 提供到此函数的简化接口。

示例

#include <iostream>
#include <sstream>
#include <locale>
 
void demo_money_get(std::locale loc, const std::string& input)
{
    std::istringstream str(input);
    str.imbue(loc);
    long double units;
// 注意:下列代码能简单地写成 std::get_money(units)
    std::ios_base::iostate err = std::ios_base::goodbit;
    std::istreambuf_iterator<char> ret =
        std::use_facet<std::money_get<char>>(loc).get(
                 std::istreambuf_iterator<char>(str),
                 std::istreambuf_iterator<char>(),
                 false, str, err, units);
    str.setstate(err);
    std::istreambuf_iterator<char> last{};
    if(str) {
        std::cout << "Successfully parsed '" << str.str() << "' as "
                  << units/100 << " units\n";
        if(ret != last) {
            std::cout << "Remaining content: '";
            std::copy(ret, last, std::ostreambuf_iterator<char>(std::cout));
            std::cout << "'\n";
        } else {
            std::cout << "The input was fully consumed\n";
        }
    } else {
            std::cout << "Parse failed. Unparsed string: '";
            std::copy(ret, last, std::ostreambuf_iterator<char>(std::cout));
            std::cout << "'\n";
    }
}
 
int main()
{
    demo_money_get(std::locale("en_US.utf8"), "-$5.12 abc");
    demo_money_get(std::locale("ms_MY.utf8"), "(RM5.12) def");
}

输出:

Successfully parsed '-$5.12 abc' as -5.12 units
Remaining content: ' abc'
Successfully parsed '(RM5.12) def' as -5.12 units
Remaining content: ' def'

参阅

定义 std::money_getstd::money_put 所用的货币格式解析器的参数
(类模板)
从输入字符序列中解析并构造货币值
(类模板)
(C++11)
剖析货币值
(函数模板)