protected:
virtual iter_type do_get(iter_type in, iter_type end, ios_base& str,
ios_base::iostate& err, bool& val) const; // (1) C++98
virtual iter_type do_get(iter_type in, iter_type end, ios_base& str,
ios_base::iostate& err, long& val) const; // (2) C++98
virtual iter_type do_get(iter_type in, iter_type end, ios_base& str,
ios_base::iostate& err, long long& val) const; // (3) C++11
virtual iter_type do_get(iter_type in, iter_type end, ios_base& str,
ios_base::iostate& err, unsigned short& val) const; // (4) C++98
virtual iter_type do_get(iter_type in, iter_type end, ios_base& str,
ios_base::iostate& err, unsigned int& val) const; // (5) C++98
virtual iter_type do_get(iter_type in, iter_type end, ios_base& str,
ios_base::iostate& err, unsigned long& val) const; // (6) C++98
virtual iter_type do_get(iter_type in, iter_type end, ios_base& str,
ios_base::iostate& err, unsigned long long& val) const; // (7) C++11
virtual iter_type do_get(iter_type in, iter_type end, ios_base& str,
ios_base::iostate& err, float& val) const; // (8) C++98
virtual iter_type do_get(iter_type in, iter_type end, ios_base& str,
ios_base::iostate& err, double& val) const; // (9) C++98
virtual iter_type do_get(iter_type in, iter_type end, ios_base& str,
ios_base::iostate& err, long double& val) const; // (10) C++98
virtual iter_type do_get(iter_type in, iter_type end, ios_base& str,
ios_base::iostate& err, void*& val) const; // (11) C++98
概要
入力イテレータ範囲[in, end)から文字列を読み取り、valの型に応じた数値・真偽値・ポインタへ変換する。get()から呼び出される、実際の解析を行う仮想関数である。
- (1) :
boolへ変換する - (2), (3) : 符号付き整数型 (
long,long long) へ変換する - (4), (5), (6), (7) : 符号なし整数型 (
unsigned short,unsigned int,unsigned long,unsigned long long) へ変換する - (8), (9), (10) : 浮動小数点数型 (
float,double,long double) へ変換する - (11) : ポインタ (
void*) へ変換する
効果
(2)〜(11)は、入力を数値へ変換する。変換は以下の3段階(Stage 1〜3)で行われる。(1)のbool版は、これらとは別に後述の規則で処理される。
Stage 1 : 変換指定の決定
str.flags()からbasefield・uppercase・boolalphaを取り出し、変換指定(および必要な長さ修飾子)を決定する。
-
(2), (3), (4), (5), (6), (7) : 以下の表の条件を上から順に評価し、最初に真となった行の変換指定を使用する
状態 stdioの変換指定に相当basefield ==ios_base::oct%obasefield ==ios_base::hex%Xbasefield == 0%i符号付き整数型 %d符号なし整数型 %u -
(8), (9), (10) :
%g - (11) :
%p
Stage 2 : 文字の抽出
[in, end)から、変換指定に合致する文字を順次抽出する。str.getloc()から取得したnumpunctファセットにより、numpunct::grouping()が空でない場合は桁区切り文字(numpunct::thousands_sep())を取り除き、小数点文字(numpunct::decimal_point())は'.'に置き換える。
Stage 3 : 数値への変換と格納
Stage 2で蓄積した文字列(フィールド)を、<cstdlib>で宣言される以下の関数の規則に従って数値へ変換する。
| オーバーロード | 対象の型 | 変換規則 |
|---|---|---|
| (2), (3) | 符号付き整数型 | std::strtoll |
| (4), (5), (6), (7) | 符号なし整数型 | std::strtoull |
| (8) | float |
std::strtof |
| (9) | double |
std::strtod |
| (10) | long double |
std::strtold |
| (11) | void* |
規定されていない |
格納される値は以下のいずれかであり、いずれの場合も結果はvalへ格納される。
- (2)〜(11) : 変換関数がフィールド全体を変換しなかった場合、
0 - (2), (3) :
valに表現できないほど大きな正(負)の値を表す場合、表現可能な最大(最小)の値 - (4), (5), (6), (7) :
valに表現できない値を表す場合、表現可能な最大の値 - (2)〜(11) : それ以外の場合、変換された値
変換関数がフィールド全体を変換しなかった場合、または表現可能な範囲外の値を表す場合、errにstd::ios_base::failbitが設定される。
桁区切りの検査
(2)〜(10)では、取り除いた桁区切り文字の位置がnumpunct::grouping()と整合しているかが検査される。整合していない場合、errにstd::ios_base::failbitが設定される。
入力終端の扱い
いずれの場合も、Stage 2の処理がin == endの判定によって終了した場合は、err |=std::ios_base::eofbitが行われる。
(1) bool版の処理
(str.flags()&std::ios_base::boolalpha) == 0の場合 :longと同様に入力を読み取り、格納しようとする値が0ならfalse、1ならtrueを格納する。それ以外の場合はtrueを格納し、errにstd::ios_base::failbitを設定する- そうでない場合 :
numpunct::truename()とnumpunct::falsename()を対象列として、一意に定まるまで文字を照合する。一意にマッチした場合は対応する値をvalへ格納する。そうでない場合はfalseを格納し、errにstd::ios_base::failbitを設定する
戻り値
- (1) : 照合に使用しなかった最初の文字を指すイテレータ
- (2)〜(11) : Stage 2で抽出を終えた位置、すなわち変換に使用しなかった最初の文字を指すイテレータ
バージョン
言語
- C++98
関連項目
参照
- LWG Issue 1169.
num_getnot fully compatible withstrto*- C++17で、
floatにstd::strtof、long doubleにstd::strtoldを使用することが明示され(std::strtoll/std::strtoull/std::strtodは変更なし)、符号なし整数型で表現できない値に対しては(正負によらず)常に表現可能な最大の値を格納する形に整理された。これによりC標準ライブラリと整合するようになった
- C++17で、