Namespaces
Variants

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

ja.cppreference.net より
 
 
 
 
 
public:
iter_type get( iter_type in, iter_type end, std::ios_base& str,
               std::ios_base::iostate& err, bool& v ) const;
(1)
iter_type get( iter_type in, iter_type end, std::ios_base& str,
               std::ios_base::iostate& err, long& v ) const;
(2)
iter_type get( iter_type in, iter_type end, std::ios_base& str,
               std::ios_base::iostate& err, long long& v ) const;
(3) (C++11 以降)
iter_type get( iter_type in, iter_type end, std::ios_base& str,
               std::ios_base::iostate& err, unsigned short& v ) const;
(4)
iter_type get( iter_type in, iter_type end, std::ios_base& str,
               std::ios_base::iostate& err, unsigned int& v ) const;
(5)
iter_type get( iter_type in, iter_type end, std::ios_base& str,
               std::ios_base::iostate& err, unsigned long& v ) const;
(6)
iter_type get( iter_type in, iter_type end, std::ios_base& str,
               std::ios_base::iostate& err, unsigned long long& v ) const;
(7) (C++11 以降)
iter_type get( iter_type in, iter_type end, std::ios_base& str,
               std::ios_base::iostate& err, float& v ) const;
(8)
iter_type get( iter_type in, iter_type end, std::ios_base& str,
               std::ios_base::iostate& err, double& v ) const;
(9)
iter_type get( iter_type in, iter_type end, std::ios_base& str,
               std::ios_base::iostate& err, long double& v ) const;
(10)
iter_type get( iter_type in, iter_type end, std::ios_base& str,
               std::ios_base::iostate& err, void*& v ) const;
(11)
protected:
virtual iter_type do_get( iter_type in, iter_type end, std::ios_base& str,
                          std::ios_base::iostate& err, bool& v ) const;
(12)
virtual iter_type do_get( iter_type in, iter_type end, std::ios_base& str,
                          std::ios_base::iostate& err, long& v ) const;
(13)
virtual iter_type do_get( iter_type in, iter_type end, std::ios_base& str,
                          std::ios_base::iostate& err, long long& v ) const;
(14) (C++11 以降)
virtual iter_type do_get( iter_type in, iter_type end, std::ios_base& str,
                          std::ios_base::iostate& err, unsigned short& v ) const;
(15)
virtual iter_type do_get( iter_type in, iter_type end, std::ios_base& str,
                          std::ios_base::iostate& err, unsigned int& v ) const;
(16)
virtual iter_type do_get( iter_type in, iter_type end, std::ios_base& str,
                          std::ios_base::iostate& err, unsigned long& v ) const;
(17)
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;
(18) (C++11 以降)
virtual iter_type do_get( iter_type in, iter_type end, std::ios_base& str,
                          std::ios_base::iostate& err, float& v ) const;
(19)
virtual iter_type do_get( iter_type in, iter_type end, std::ios_base& str,
                          std::ios_base::iostate& err, double& v ) const;
(20)
virtual iter_type do_get( iter_type in, iter_type end, std::ios_base& str,
                          std::ios_base::iostate& err, long double& v ) const;
(21)
virtual iter_type do_get( iter_type in, iter_type end, std::ios_base& str,
                          std::ios_base::iostate& err, void*& v ) const;
(22)
1-11) パブリックメンバ関数。最派生クラスのメンバ関数 do_get を呼び出します。
12-22) 入力イテレータ in から文字を読み取り、v の型の値を生成します。str.flags() からの I/O ストリームのフォーマットフラグ、std::use_facet<std::ctype<CharT>>(str.getloc()) からの文字分類ルール、std::use_facet<std::numpunct<CharT>>(str.getloc()) からの数値句読点文字を考慮します。この関数は、std::cin >> n; のようなすべての書式付き入力ストリーム演算子によって呼び出されます。

変換は3つの段階で行われます:

Stage 1: 変換指定子の選択

  • I/O フォーマットフラグは、以下のように取得されます
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 を使用します
  • 整数型の場合、必要に応じて変換指定子に長さ修飾子が追加されます: h ( short および unsigned short 用)、 l ( long および unsigned long 用) 、 ll ( long long および unsigned long long 用) (C++11以降)
  • v の型が float の場合、変換指定子 % g を使用します
  • v の型が double の場合、変換指定子 % lg を使用します
  • v の型が long double の場合、変換指定子 % Lg を使用します
  • v の型が void * の場合、変換指定子 % p を使用します
  • v の型が bool であり、かつ boolalpha == 0 の場合、 v の型が long であるかのように処理されます(ステージ3で v に格納される値を除く)
  • 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 値が設定されます。それ以外の場合、 false が v に格納され、 std::ios_base::failbit が err に割り当てられます。入力が終了する前に一意のマッチが見つからなかった場合( in == end )、 err | = std:: ios_base :: eofbit が実行されます

ステージ2: 文字抽出

  • in == end の場合、ステージ2は直ちに終了し、それ以上文字は抽出されません。
  • 次の文字は in から char_type ct = *in; によるかのように抽出されます:
    • その文字が "0123456789abcdefxABCDEFX+-"(C++11までは)"0123456789abcdefpxABCDEFPX+-"(C++11以降は) のいずれかに一致し、std::use_facet<std::ctype<CharT>>(str.getloc()).widen() によるかのようにロケールの char_type に拡大された場合、対応する 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は終了します。

Stage 3: 変換と保存

  • ステージ2で蓄積された char のシーケンスは数値に変換されます:
入力は std::scanf の規則に従って解析されます。
(C++11まで)
入力は以下のように解析されます:
(C++11以降)
  • 変換関数がフィールド全体の変換に失敗した場合、値 ​ 0 ​ が v に格納される。
  • v の型が符号付き整数型であり、変換関数の結果が格納できない正または負の大きすぎる値である場合、それぞれ表現可能な最大の正の値または最小の負の値が v に格納される。
  • v の型が符号なし整数型であり、変換関数の結果が格納できない値である場合、表現可能な最大の正の値が v に格納される。
  • いずれの場合も、変換関数が失敗した場合 std::ios_base::failbit が err に設定される。
  • それ以外の場合、変換の数値結果が v に格納される。
    • v の型が bool であり、かつboolalphaが設定されていない場合、格納される値が ​ 0 ​ なら false が格納され、格納される値が 1 なら true が格納され、それ以外の値の場合 std::ios_base::failbit が err に設定され、 true が格納される。
  • その後、数字のグループ化がチェックされる。ステージ2で破棄された千単位区切り文字の位置が std:: use_facet < std:: numpunct < CharT >> ( str. getloc ( ) ) . grouping ( ) によって提供されるグループ化と一致しない場合、 std::ios_base::failbit が err に設定される。
  • ステージ2がテスト in == end によって終了した場合、 err | = std:: ios_base :: eofbit が実行され、EOFビットが設定される。

戻り値

in

注記

LWG issue 23 および LWG issue 696 の解決以前は、エラーが発生した場合 v は変更されないまま残されていました。

LWG issue 221 が解決される前は、16進整数を表す文字列(例: "0xA0" )は、 strtol への有効な入力であっても、 do_get(int) によって拒否されていました。これは、ステージ2で文字 'X' と 'x' がフィルタリングされるためです。

LWG issue 1169 が解決される前は、負数の文字列を符号なし整数に変換すると、ゼロが生成される可能性がありました(文字列が表す値がターゲット型が表現できる値よりも小さいため)。

LWG issue 2381 の解決以前は、指数部を持つ16進浮動小数点数を表す文字列(例: "0x1.23p-10" )は、 strtod への有効な入力であっても、 do_get(double) によって拒否されていました。これは、ステージ2が文字 'P' および 'p' をフィルタリングするためです。

無限大または非数を表す文字列(例: "NaN" および "inf" )は、 strtod への有効な入力であっても、 do_get(double) によって拒否されていました。これは、ステージ2が 'N' や 'i' などの文字をフィルタリングするためです。

(C++11以降)

例

ユーザー定義型の 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;
}

不具合報告

以下の動作変更の欠陥報告書は、以前に公開されたC++規格に対して遡及的に適用されました。

DR 適用対象 公開時の動作 修正後の動作
LWG 17 C++98 テキストのブール値の解析プロセスに誤りがあった 修正済み
LWG 18 C++98 get の bool & 値を取るオーバーロードが欠落していた 追加済み
LWG 23 C++98 入力オーバーフローが未定義動作を引き起こした オーバーフロー処理を実装
LWG 154 C++98 double の変換指定子が % g ( float と同じ)だった % lg に変更
LWG 221 C++98 do_get が 'x' と 'X' を解析しないが、 strtol は解析していた 'x' と 'X' を解析するように修正
LWG 275 C++98 get が short & 値を取るオーバーロードを持っていた( float & ではなく) 修正済み
LWG 358 C++98 小数点以下の桁区切り文字が無視されていた 検出された場合にステージ2を終了
LWG 696 C++98 変換失敗時に結果が変更されなかった ゼロに設定
LWG 1169 C++98 浮動小数点型間でオーバーフロー処理が一貫していなかった strtof / strtod と一貫性を持たせた
LWG 2381 C++11 do_get が 'p' と 'P' を解析しないが、 strtod は解析していた 'p' と 'P' を解析するように修正

関連項目

書式化データを抽出
( std::basic_istream<CharT,Traits> の公開メンバー関数)