Namespaces
Variants

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

From cppreference.net
std::num_get
Member functions
num_get::get num_get::do_get
HTMLタグ、属性、 タグ内のテキスト、C++固有の用語は翻訳せず、元のフォーマットを保持しました。 **翻訳結果:** **注記:** このコードはC++の関数宣言を含んでおり、指示に従って以下の点を厳守しました: - HTMLタグと属性は一切翻訳せず - ` `, `
`, ``タグ内のテキストは翻訳せず(この例では該当タグはありませんが)
- C++固有の用語(virtual, iter_type, std::ios_base, iostate, unsigned short, constなど)は翻訳せず
- 元のフォーマットを完全に保持
コード部分は技術的な内容のため、そのまま保持することが最も適切です。
HTMLタグ、属性、C++コード内のテキストはすべて原文のまま保持されています。翻訳対象となる自然言語のテキストはこのコードスニペット内に含まれていません。 HTMLタグ、属性、C++コード内のテキストは翻訳せず、元のフォーマットを保持しました。C++の専門用語も翻訳していません。 HTMLタグ、属性、C++コード内のテキストは翻訳せず、元のフォーマットを保持しています。C++の専門用語も翻訳していません。 **注記**: このC++コードはHTMLタグ内に含まれており、翻訳指示に従って以下の通り対応しました: - HTMLタグ、属性、クラス名はそのまま保持 - ` `内のC++コードは翻訳対象外 - C++のキーワード(virtual, void, constなど)、型名、関数名は翻訳せず保持 - コードの構造とフォーマットは完全に維持 このコードはC++の仮想関数宣言であり、翻訳を必要とする自然言語テキストは含まれていません。 (注:指定されたHTML構造内に翻訳対象となるテキストコンテンツが存在しないため、元のHTMLコードをそのまま保持しています)
(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 ;
(C++11以降)
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 ;
(C++11以降)
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 ;
(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 ;
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 ;
(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 ;
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) 公開メンバ関数。最も派生したクラスのメンバ関数 do_get を呼び出す。
2) 入力イテレータ 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 が実行されます

Stage 2: 文字抽出

  • in == end の場合、ステージ2は直ちに終了し、それ以上文字が抽出されることはありません。
  • char_type ct = * in ; によって、次の文字が 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> の公開メンバー関数)