std::num_get<CharT,InputIt>:: get, std::num_get<CharT,InputIt>:: do_get
| (1) | ||
|
public
:
iter_type get
(
iter_type in, iter_type end,
std::
ios_base
&
str,
|
||
|
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,
|
||
|
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,
|
(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 ; |
||
do_get
を呼び出す。
変換は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 のシーケンスは数値に変換されます:
|
(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
への有効な入力であっても、
無限大または非数を表す文字列(例:
"NaN"
および
"inf"
)は、
|
(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>
の公開メンバー関数)
|