名前空間
変種
操作

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

提供: cppreference.com
< cpp‎ | locale‎ | num get
 
 
 
std::num_get
メンバ関数
num_get::getnum_get::do_get
 
(1)
public:

iter_type get( iter_type in, iter_type end, std::ios_base& str,

               std::ios_base::iostate& err, bool& v ) const;
iter_type get( iter_type in, iter_type end, std::ios_base& str,
               std::ios_base::iostate& err, long& v ) const;
iter_type get( iter_type in, iter_type end, std::ios_base& str,
               std::ios_base::iostate& err, long long& v ) const;
iter_type get( iter_type in, iter_type end, std::ios_base& str,
               std::ios_base::iostate& err, unsigned short& v ) const;
iter_type get( iter_type in, iter_type end, std::ios_base& str,
               std::ios_base::iostate& err, unsigned int& v ) const;
iter_type get( iter_type in, iter_type end, std::ios_base& str,
               std::ios_base::iostate& err, unsigned long& v ) const;
iter_type get( iter_type in, iter_type end, std::ios_base& str,
               std::ios_base::iostate& err, unsigned long long& v ) const;
iter_type get( iter_type in, iter_type end, std::ios_base& str,
               std::ios_base::iostate& err, float& v ) const;
iter_type get( iter_type in, iter_type end, std::ios_base& str,
               std::ios_base::iostate& err, double& v ) const;
iter_type get( iter_type in, iter_type end, std::ios_base& str,
               std::ios_base::iostate& err, long double& v ) const;
iter_type get( iter_type in, iter_type end, std::ios_base& str,
               std::ios_base::iostate& err, void*& v ) const;
(2)
protected:

virtual iter_type do_get( iter_type in, iter_type end, std::ios_base& str,

                          std::ios_base::iostate& err, bool& v ) const;
virtual iter_type do_get( iter_type in, iter_type end, std::ios_base& str,
                          std::ios_base::iostate& err, long& v ) const;
virtual iter_type do_get( iter_type in, iter_type end, std::ios_base& str,
                          std::ios_base::iostate& err, long long& v ) const;
virtual iter_type do_get( iter_type in, iter_type end, std::ios_base& str,
                          std::ios_base::iostate& err, unsigned short& v ) const;
virtual iter_type do_get( iter_type in, iter_type end, std::ios_base& str,
                          std::ios_base::iostate& err, unsigned int& v ) const;
virtual iter_type do_get( iter_type in, iter_type end, std::ios_base& str,
                          std::ios_base::iostate& err, unsigned long& v ) const;
virtual iter_type do_get( iter_type in, iter_type end, std::ios_base& str,
                          std::ios_base::iostate& err, unsigned long long& v ) const;
virtual iter_type do_get( iter_type in, iter_type end, std::ios_base& str,
                          std::ios_base::iostate& err, float& v ) const;
virtual iter_type do_get( iter_type in, iter_type end, std::ios_base& str,
                          std::ios_base::iostate& err, double& v ) const;
virtual iter_type do_get( iter_type in, iter_type end, std::ios_base& str,
                          std::ios_base::iostate& err, long double& v ) const;
virtual iter_type do_get( iter_type in, iter_type end, std::ios_base& str,
                          std::ios_base::iostate& err, void*& v ) const;
1) public メンバ関数。 最も派生したクラスのメンバ関数 do_get を呼びます。
2) 入力イテレータ in から文字を読み込み、 str.flags() の入出力ストリーム書式化フラグ、 std::use_facet<std::ctype<charT>>(str.getloc()) の文字分類ルール、 std::use_facet<std::numpunct<charT>>(str.getloc()) の数値の句読点文字を考慮し、 v 型の値を生成します。 この関数は std::cin >> n; などのすべての書式付き入力ストリーム操作によって呼ばれます。

変換は3つのステージで行われます。

目次

[編集] ステージ1: 変換指定子の選択

  • 以下によって行われたかのように、入出力書式フラグが取得されます。
fmtflags basefield = (str.flags() & std::ios_base::basefield);
fmtflags boolalpha = (str.flags() & std::ios_base::boolalpha);
  • v の型が整数型の場合は、以下の5つのうち最初に適用可能なものが選択されます。
basefield == oct の場合は、変換指定子 %o を使用します。
basefield == hex の場合は、変換指定子 %X を使用します。
basefield == 0 の場合は、変換指定子 %i を使用します。
v の型が符号付きの場合は、変換指定子 %d を使用します。
v の型が符号なしの場合は、変換指定子 %u を使用します。
  • 整数型の場合は、必要であれば変換指定子に長さ修飾子が追加されます (short および unsigned short に対しては hlong および unsigned long に対しては llong long および unsigned long long に対しては ll)。
  • v の型が float の場合は、変換指定子 %g を使用します。
  • v の型が double の場合は、変換指定子 %lg を使用します。
  • v の型が long double の場合は、変換指定子 %Lg を使用します。
  • v の型が void* の場合は、変換指定子 %p を使用します。
  • v の型が bool であり boolalpha==0 の場合は、ステージ3の v に格納される値を除いて、 vlong 型であるかのように続行します。
  • v の型が bool であり boolalpha!=0 の場合は、ステージ2と3を以下で置き換えます。
    • 入力イテレータ in から取得した連続する文字が、一意なマッチを識別するために必要なだけ、 std::use_facet<std::numpunct<charT>>(str.getloc()).falsename() および std::use_facet<std::numpunct<charT> >(str.getloc()).truename() から取得した文字シーケンスに対してマッチされます。 入力イテレータ in は、文字を取得するために必要なときにのみ、 end と比較されます。
    • ターゲットシーケンスが一意にマッチした場合、 v は対応する bool 値に設定されます。 そうでなければ、 falsev に格納され、 std::ios_base::failbiterr に代入されます。 入力が終了する前に一意なマッチが見つからなかった場合は、 err|=std::ios_base::eofbit が実行されます。

[編集] ステージ2: 文字の抽出

  • in==end の場合、ステージ2は直ちに終了し、それ以上の文字は抽出されません。
  • char_type ct = *in; によって行われたかのように、次の文字が in から抽出されます。
    • その文字が、 std::use_facet<std::ctype<charT>>(str.getloc()).widen() によって行われたかのようにロケールの char_type でワイド化された "0123456789abcdefxABCDEFX+-" のいずれかにマッチする場合は、それが対応する char に変換されます。
    • その文字が小数点区切り文字 (std::use_facet<std::numpunct<charT>>(str.getloc()).decimal_point())) にマッチする場合、それは '.' に置き換えられます。
    • その文字が桁区切り文字 (std::use_facet<std::numpunct<charT>>(str.getloc()).thousands_sep()) にマッチし、そもそも桁区切り文字が使用されている (std::use_facet<std::numpunct<charT>>(str.getloc()).grouping().length() != 0) 場合は、小数点 '.' がまだ蓄積されていなければ、その文字の位置が記憶されますが、それ以外の点では、その文字は無視されます。 小数点がすでに蓄積されている場合は、その文字は破棄され、ステージ2を終了します。
    • いずれの場合も、以前のステップで取得した char が、ステージ1で選択された変換指定子を与えた std::scanf によって解析される入力フィールドで許容されるかどうか、チェックが行われます。 許容される場合、それは一時バッファに蓄積され、ステージ2を繰り返します。 許容されない場合、ステージ2は終了します。

[編集] ステージ3: 変換と記憶域

  • ステージ2で蓄積された char のシーケンスが数値に変換されます。
入力は、ステージ1で選択された変換指定子を与えた std::scanf で行われたかのように、解析されます。
(C++11未満)
入力は、符号付き整数 v の場合は std::strtoll、符号なし整数 v の場合は std::strtoull、浮動小数点 v の場合は std::strtold によって行われたかのように、解析されます。
(C++11以上)
(C++17未満)
入力は、符号付き整数 v の場合は std::strtoll、符号なし整数 v の場合は std::strtoullfloat v の場合は std::strtofdouble v の場合は std::strtodlong double v の場合は std::strtold によって行われたかのように、解析されます。
(C++17以上)
  • 変換関数がフィールド全体の変換に失敗した場合は、値 0v に格納されます。
  • 変換関数の結果が v の型に収めるには大きすぎる正の値の場合は、表現可能な最も大きな正の値が v に格納されます。
  • 変換関数の結果が v の型に収めるには小さすぎる負の値の場合は、表現可能な最も小さな負の値または符号なし整数型の場合はゼロ (C++17未満)v に格納されます。
(C++11以上)
  • いずれの場合も、変換関数が失敗した場合は std::ios_base::failbiterr に代入されます。
  • そうでなければ、変換の結果の数値が v に格納されます。
    • v の型が bool であり、 boolalpha がセットされていない場合、格納される値が 0 であれば

false が格納され、格納される値が 1 であれば true が格納され、それ以外のあらゆる値に対しては std::ios_base::failbiterr に代入され、 true が格納されます。

  • この後、桁のグループ化がチェックされます。 ステージ2で破棄されたあらゆる桁区切り文字の位置が std::use_facet<std::numpunct<charT>>(str.getloc()).grouping() によって提供されるグループ化にマッチしない場合は、 std::ios_base::failbiterr に代入されます。
  • ステージ2が in==end の確認によって終了した場合は、 eof ビットをセットするために err|=std::ios_base::eofbit が実行されます。

[編集] 戻り値

in

[編集] ノート

C++98/C++03 では、エラーが発生した場合、 v は変更されません。 C++11 では、上の説明通りの値に設定されます。

負の数値の文字列の符号なし整数への変換の結果は、 C++17 まではゼロを生成すると規定されていましたが、一部の処理系は目的の型で否定する ("-1" に対して ULLONG_MAX を与える) std::strtoull の規約に従っており、そのため代わりに目的の型の最も大きな値を生成しました。 C++17 以降は、 std::strtoull に厳密に従うことが正しい動作です。

ステージ2は 'p', 'N', 'i' などの文字を除去するため、 "0x1.23p-10" などの16進浮動小数点数や、文字列 "NaN"、 "inf" などは、 strtod への入力としては有効であっても、 do_get(double) によって拒否されることがあります。 LWG #2381 も参照してください。

[編集]

ユーザ定義型のための operator>> の実装。

#include <iostream>
#include <iterator>
#include <locale>
 
struct base { long x; };
 
template <class CharT, class Traits>
std::basic_istream<CharT, Traits>&
    operator >>(std::basic_istream<CharT, Traits>& is,
                base& b)
{
    std::ios_base::iostate err = std::ios_base::goodbit;
    try // setting err could throw
    {
        typename std::basic_istream<CharT, Traits>::sentry s(is);
 
        if (s) // if stream is ready for input
        {
            std::use_facet<std::num_get<CharT>>(is.getloc()).get(is, {}, is, err, b.x);
        }
    } catch(std::ios_base::failure& error)
    {
        // handle the exception
    }
    return is;
}
 
int main()
{
    base b;
 
    std::cin >> b;
}


[編集] 関連項目

書式付きデータを抽出します
(std::basic_istream<CharT,Traits>のパブリックメンバ関数) [edit]