std::num_put<CharT,OutputIt>:: put, std::num_put<CharT,OutputIt>:: do_put
|
ヘッダーで定義
<locale>
|
||
| (1) | ||
|
public
:
iter_type put
(
iter_type out,
std::
ios_base
&
str,
|
||
|
iter_type put
(
iter_type out,
std::
ios_base
&
str,
char_type fill, long val ) const ; |
||
|
iter_type put
(
iter_type out,
std::
ios_base
&
str,
char_type fill, long long val ) const ; |
(C++11以降) | |
|
iter_type put
(
iter_type out,
std::
ios_base
&
str,
char_type fill, unsigned long val ) const ; |
||
|
iter_type put
(
iter_type out,
std::
ios_base
&
str,
char_type fill, unsigned long long val ) const ; |
(C++11以降) | |
|
iter_type put
(
iter_type out,
std::
ios_base
&
str,
char_type fill, double val ) const ; |
||
|
iter_type put
(
iter_type out,
std::
ios_base
&
str,
char_type fill, long double val ) const ; |
||
|
iter_type put
(
iter_type out,
std::
ios_base
&
str,
char_type fill, const void * val ) const ; |
||
| (2) | ||
|
protected
:
virtual
iter_type do_put
(
iter_type out,
std::
ios_base
&
str,
|
||
|
virtual
iter_type do_put
(
iter_type out,
std::
ios_base
&
str,
char_type fill, long val ) const ; |
||
|
virtual
iter_type do_put
(
iter_type out,
std::
ios_base
&
str,
char_type fill, long long val ) const ; |
(C++11以降) | |
|
virtual
iter_type do_put
(
iter_type out,
std::
ios_base
&
str,
char_type fill, unsigned long val ) const ; |
||
|
virtual
iter_type do_put
(
iter_type out,
std::
ios_base
&
str,
char_type fill, unsigned long long val ) const ; |
(C++11以降) | |
|
virtual
iter_type do_put
(
iter_type out,
std::
ios_base
&
str,
char_type fill, double val ) const ; |
||
|
virtual
iter_type do_put
(
iter_type out,
std::
ios_base
&
str,
char_type fill, long double val ) const ; |
||
|
virtual
iter_type do_put
(
iter_type out,
std::
ios_base
&
str,
char_type fill, const void * val ) const ; |
||
do_put
を呼び出す。
変換は4つの段階で行われます:
目次 |
Stage 1: 変換指定子の選択
- I/O フォーマットフラグは、以下のようにして取得されます
- fmtflags basefield = ( str. flags ( ) & std:: ios_base :: basefield ) ;
- fmtflags uppercase = ( str. flags ( ) & std:: ios_base :: uppercase ) ;
- fmtflags floatfield = ( str. flags ( ) & std:: ios_base :: floatfield ) ;
- fmtflags showpos = ( str. flags ( ) & std:: ios_base :: showpos ) ;
- fmtflags showbase = ( str. flags ( ) & std:: ios_base :: showbase ) ;
- fmtflags showpoint = ( str. flags ( ) & std:: ios_base :: showpoint ) ;
-
val
の型が
bool
の場合:
- boolalpha == 0 の場合、 val を int 型に変換して整数出力を実行する。
- boolalpha ! = 0 の場合、 std:: use_facet < std:: numpunct < CharT >> ( str. getloc ( ) ) . truename ( ) を val == true の場合に取得し、または std:: use_facet < std:: numpunct < CharT >> ( str. getloc ( ) ) . falsename ( ) を val == false の場合に取得し、その文字列の各連続する文字 c を * out ++ = c で out に出力する。この場合、それ以上の処理は行われず、関数は out を返す。
-
val
の型が整数型の場合、以下のうち最初に適用可能な選択肢が選ばれる:
- basefield == oct の場合、変換指定子 % o を使用する。
- basefield == hex && ! uppercase の場合、変換指定子 % x を使用する。
- basefield == hex の場合、変換指定子 % X を使用する。
- val の型が符号付きの場合、変換指定子 % d を使用する。
- val の型が符号なしの場合、変換指定子 % u を使用する。
- 整数型の場合、必要に応じて変換指定に長さ修飾子が追加される: l が long および unsigned long に、 ll が long long および unsigned long long に使用される (C++11以降) 。
- val の型が浮動小数点型の場合、以下のうち最初に適用可能な選択肢が選ばれる:
|
(C++11以前) |
|
(C++11以降) |
-
- floatfield == std:: ios_base :: scientific && ! uppercase の場合、変換指定子 % e を使用します。
- floatfield == std:: ios_base :: scientific の場合、変換指定子 % E を使用します。
|
(C++11以降) |
-
- ! uppercase の場合、変換指定子 % g を使用します。
- それ以外の場合、変換指定子 % G を使用します。
-
また:
- val の型が long double の場合、長さ修飾子 L が変換指定子に追加されます。
- val の型が浮動小数点型 であり、かつ floatfield ! = ( ios_base :: fixed | ios_base :: scientific ) (C++11以降) の場合、精度修飾子が追加され str. precision ( ) に設定されます。それ以外の場合、精度は指定されません。
- 整数型および浮動小数点型の両方について、 showpos が設定されている場合、修飾子 + が先頭に付加されます。
- 整数型について、 showbase が設定されている場合、修飾子 # が先頭に付加されます。
- 浮動小数点型について、 showpoint が設定されている場合、修飾子 # が先頭に付加されます。
- val の型が void * の場合、変換指定子 % p を使用します。
- ナロー文字列は、"C"ロケールにおける std:: printf ( spec, val ) の呼び出しによって生成されます。ここで spec は選択された変換指定子です。
Stage 2: ロケール固有の変換
-
ステージ1で取得されたすべての文字
c
は、小数点
'.'
を除き、
std::
use_facet
<
std::
ctype
<
CharT
>>
(
str.
getloc
(
)
)
.
widen
(
c
)
を呼び出すことで
CharTに変換されます。 - 算術型の場合、 std:: use_facet < std:: numpunct < CharT >> ( str. getloc ( ) ) . thousands_sep ( ) から取得した千単位区切り文字が、 std:: use_facet < std:: numpunct < CharT >> ( str. getloc ( ) ) . grouping ( ) によって提供されるグループ化ルールに従ってシーケンスに挿入されます。
- 小数点文字( '.' )は std:: use_facet < std:: numpunct < CharT >> ( str. getloc ( ) ) . decimal_point ( ) で置き換えられます。
Stage 3: パディング
-
調整フラグは、以下のようにして取得され、
std
::
fmtflags
adjustfield
=
(
flags
&
(
std::
ios_base
::
adjustfield
)
)
パディング位置を特定するために検査されます:
- adjustfield == std:: ios_base :: left の場合、後ろにパディングします。
- adjustfield == std:: ios_base :: right の場合、前にパディングします。
- adjustfield == std:: ios_base :: internal で、かつ表現に符号文字が含まれる場合、符号の後にパディングします。
- adjustfield == std:: ios_base :: internal で、かつステージ1の表現が0xまたは0Xで始まる場合、xまたはXの後にパディングします。
- それ以外の場合、前にパディングします。
-
str.
width
(
)
が非ゼロ(例:
std::setw
が使用された直後)で、ステージ2後の
CharTの数が str. width ( ) より少ない場合、パディング位置に fill 文字のコピーが挿入され、シーケンスの長さが str. width ( ) に達するように調整されます。
いずれの場合でも、 str. width ( 0 ) が呼び出され、 std::setw の効果をキャンセルします。
Stage 4: 出力
連続する各文字
c
は、ステージ3からの
CharT
シーケンスから、
*
out
++
=
c
によって出力されるかのように出力されます。
パラメータ
| out | - | 上書きされる最初の文字を指すイテレータ |
| str | - | 書式情報を取得するストリーム |
| fill | - | フィールド幅にパディングが必要な場合に使用されるパディング文字 |
| val | - | 文字列に変換して出力する値 |
戻り値
out
注記
変換指定 #o によって生成される先行ゼロ(例えば std::showbase と std::oct の組み合わせによる結果)は、パディング文字としてはカウントされません。
|
浮動小数点値をhexfloatとしてフォーマットする場合(すなわち、 floatfield == ( std:: ios_base :: fixed | std:: ios_base :: scientific ) の場合)、ストリームの精度は使用されない。代わりに、値の正確な表現に十分な精度で常に数値が出力される。 |
(C++11以降) |
例
facetを直接使用して数値を出力し、ユーザー定義facetを実演します:
#include <iostream> #include <locale> // this custom num_put outputs squares of all integers (except long long) struct squaring_num_put : std::num_put<char> { iter_type do_put(iter_type out, std::ios_base& str, char_type fill, long val) const { return std::num_put<char>::do_put(out, str, fill, val * val); } iter_type do_put(iter_type out, std::ios_base& str, char_type fill, unsigned long val) const { return std::num_put<char>::do_put(out, str, fill, val * val); } }; int main() { auto& facet = std::use_facet<std::num_put<char>>(std::locale()); facet.put(std::cout, std::cout, '0', 2.71); std::cout << '\n'; std::cout.imbue(std::locale(std::cout.getloc(), new squaring_num_put)); std::cout << 6 << ' ' << -12 << '\n'; }
出力:
2.71 36 144
ユーザー定義型に対する operator<< の実装例。
#include <iostream> #include <iterator> #include <locale> struct base { long x = 10; }; template<class CharT, class Traits> std::basic_ostream<CharT, Traits>& operator<<(std::basic_ostream<CharT, Traits>& os, const base& b) { try { typename std::basic_ostream<CharT, Traits>::sentry s(os); if (s) { std::ostreambuf_iterator<CharT, Traits> it(os); std::use_facet<std::num_put<CharT>>(os.getloc()) .put(it, os, os.fill(), b.x); } } catch (...) { // set badbit on os and rethrow if required } return os; } int main() { base b; std::cout << b; }
出力:
10
不具合報告
以下の動作変更の欠陥報告書は、以前に公開されたC++規格に対して遡及的に適用されました。
| DR | 適用対象 | 公開時の動作 | 正しい動作 |
|---|---|---|---|
| LWG 34 | C++98 |
bool
オーバーロードが存在しないメンバ
truename と falsename を使用していた ( std::ctype のメンバ) |
これらのメンバを
std::numpunct のメンバを使用するように修正 |
| LWG 231 | C++98 |
精度修飾子は
( flags & fixed ) ! = 0 または str. precision ( ) > 0 の場合のみ追加されていた |
これらの条件を削除 |
| LWG 282 | C++98 |
千の区切り文字はステージ2で
整数型に対してのみ挿入されていた |
浮動小数点型に対しても
挿入するように修正 |
| LWG 4084 | C++11 | "NAN" と "INF" を出力できなかった | 出力可能に修正 |
関連項目
|
フォーマット済みデータを挿入
(
std::basic_ostream<CharT,Traits>
の公開メンバ関数)
|