最終更新日時:
が更新

履歴 編集

function
<locale>

std::money_get::get

iter_type
  get(iter_type s,
      iter_type end,
      bool intl,
      ios_base& f,
      ios_base::iostate& err,
      long double& quant) const;  // (1) C++98

iter_type
  get(iter_type s,
      iter_type end,
      bool intl,
      ios_base& f,
      ios_base::iostate& err,
      string_type& quant) const;  // (2) C++98

概要

入力イテレータ範囲[s, end)から金額を解析する。

  • (1) : 解析結果を整数値としてquantへ格納する
  • (2) : 解析結果を数字の列(負の場合は先頭にマイナス符号)としてquantへ格納する

intltrueの場合、国際通貨表現(moneypunct<charT, true>)の書式が使用される。

戻り値

基本的な使い方

#include <iostream>
#include <sstream>
#include <locale>
#include <iterator>
#include <string>

int main()
{
  std::istringstream iss{"105623"};
  const auto& facet = std::use_facet<std::money_get<char>>(iss.getloc());

  std::ios_base::iostate err = std::ios_base::goodbit;
  long double units = 0;

  facet.get(std::istreambuf_iterator<char>{iss},
            std::istreambuf_iterator<char>{},
            false, iss, err, units);

  // 小数点以下の桁を含む整数値として解釈される
  std::cout << units << std::endl;
}

出力

105623

ロケール依存の通貨フォーマットを解析する

金額の書式は、get()へ渡すストリームのロケールに設定されたstd::moneypunctファセットから取得される。そのため、名前付きロケールを指定するだけで、各国の通貨の書式で書かれた文字列を解析できる。

#include <iostream>
#include <sstream>
#include <locale>
#include <iterator>
#include <string>
#include <stdexcept>

// 解析の処理自体はロケールに依存しない
long double parse_money(const std::locale& loc, const std::string& text)
{
  std::istringstream iss{text};
  iss.imbue(loc);

  const auto& facet = std::use_facet<std::money_get<char>>(iss.getloc());

  std::ios_base::iostate err = std::ios_base::goodbit;
  long double units = 0;

  facet.get(std::istreambuf_iterator<char>{iss},
            std::istreambuf_iterator<char>{},
            false, iss, err, units);

  if (err & std::ios_base::failbit) {
    throw std::runtime_error("parse failed");
  }
  return units;
}

int main()
{
  const char* names[] = {"en_US.UTF-8", "ja_JP.UTF-8", "de_DE.UTF-8"};
  const char* texts[] = {"$1,056.23", "¥105,623", "1.056,23 €"};

  for (int i = 0; i < 3; ++i) {
    try {
      long double units = parse_money(std::locale{names[i]}, texts[i]);

      // ロケールごとの書式を解析しても、同じ最小単位の整数値が得られる
      std::cout << names[i] << " : " << static_cast<long long>(units) << std::endl;
    }
    catch (const std::runtime_error&) {
      std::cout << names[i] << " : not available" << std::endl;
    }
  }
}

出力例

en_US.UTF-8 : 105623
ja_JP.UTF-8 : 105623
de_DE.UTF-8 : 105623

  • 米ドルの$1,056.23とドイツのユーロの1.056,23 €は、桁区切りと小数点の文字も通貨記号の位置も異なるが、いずれも最小単位(セント)での105623として解析される
  • 日本円の¥105,623frac_digits()0であるため、105623がそのまま円単位の金額として解析される
  • 妥当なロケール名は処理系定義である。指定した名前のロケールが利用できない場合、std::localeのコンストラクタはstd::runtime_errorを送出し、上記の例ではnot availableが出力される

バージョン

言語

  • C++98

関連項目