std::num_put<CharT,OutputIt>::put, std::num_put<CharT,OutputIt>::do_put
提供: cppreference.com
<tbody>
</tbody>
<tbody class="t-dcl-rev t-dcl-rev-num ">
</tbody><tbody>
</tbody>
<tbody class="t-dcl-rev t-dcl-rev-num ">
</tbody><tbody>
</tbody>
| ヘッダ <locale> で定義
|
||
| (1) | ||
public: iter_type put( iter_type out, std::ios_base& str, char_type fill, bool v ) const; |
||
iter_type put( iter_type out, std::ios_base& str, char_type fill, long v ) const; |
||
iter_type put( iter_type out, std::ios_base& str, char_type fill, long long v ) const; |
(C++11以上) | |
iter_type put( iter_type out, std::ios_base& str, char_type fill, unsigned long v ) const; |
||
iter_type put( iter_type out, std::ios_base& str, char_type fill, unsigned long long v ) const; |
(C++11以上) | |
iter_type put( iter_type out, std::ios_base& str, char_type fill, double v ) const; |
||
iter_type put( iter_type out, std::ios_base& str, char_type fill, long double v ) const; |
||
iter_type put( iter_type out, std::ios_base& str, char_type fill, const void* v ) const; |
||
| (2) | ||
protected: virtual iter_type do_put( iter_type out, std::ios_base& str, char_type fill, bool v ) const; |
||
virtual iter_type do_put( iter_type out, std::ios_base& str, char_type fill, long v ) const; |
||
virtual iter_type do_put( iter_type out, std::ios_base& str, char_type fill, long long v ) const; |
(C++11以上) | |
virtual iter_type do_put( iter_type out, std::ios_base& str, char_type fill, unsigned long ) const; |
||
virtual iter_type do_put( iter_type out, std::ios_base& str, char_type fill, unsigned long long ) const; |
(C++11以上) | |
virtual iter_type do_put( iter_type out, std::ios_base& str, char_type fill, double v ) const; |
||
virtual iter_type do_put( iter_type out, std::ios_base& str, char_type fill, long double v ) const; |
||
virtual iter_type do_put( iter_type out, std::ios_base& str, char_type fill, const void* v ) const; |
||
1) public メンバ関数。 最も派生したクラスの protected virtual メンバ関数
do_put を呼びます。2) ストリーム
str に設定されているロケールの書式化フラグ str.flags()、ファセット std::numpunct および std::ctype によって要求される通りに書式化して、 v の値を表す文字列を出力シーケンス out に書き込みます。 この関数は std::cout << n; などのすべての書式付き出力ストリーム演算子によって呼ばれます。変換は4つのステージで行われます。
ステージ1: 変換指定子の選択
- 以下によって行われたかのように、入出力書式化フラグが取得されます。
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);
vの型がboolの場合、boolalpha == 0の場合は、vをint型変換し、整数の出力を行います。boolalpha != 0の場合は、v == trueであればstd::use_facet<std::numpunct<charT>>(str.getloc()).truename()を、v == falseであればstd::use_facet<std::numpunct<charT>>(str.getloc()).falsename()を取得し、その文字列の連続するそれぞれの文字cを*out++ = cでoutに出力します。 この場合、以降の処理は行われず、この関数はoutを返します。
vの型が整数型の場合は、以下のうち最初に適用可能なものが選択されます。
basefield == octの場合は、変換指定子%oを使用します。basefield == hex && !uppercaseの場合は、変換指定子%xを使用します。basefield == hexの場合は、変換指定子%Xを使用します。vの型が符号付きの場合は、変換指定子%dを使用します。vの型が符号なしの場合は、変換指定子%uを使用します。
- 整数型の場合、必要であれば変換指定子に長さ修飾子 (
longおよびunsigned longの場合はl、long longおよびunsigned long longの場合はll(C++11以上)) が追加されます。 vの型が浮動小数点型の場合、以下のうち最初に適用可能なものが選択されます。
floatfield == std::ios_base::fixedの場合は、変換指定子%fを使用します。floatfield == std::ios_base::scientific && !uppercaseの場合は、変換指定子%eを使用します。floatfield == std::ios_base::scientificの場合は、変換指定子%Eを使用します。
|
(C++11以上) |
!uppercaseの場合は、変換指定子%gを使用します。- そうでなければ、変換指定子
%Gを使用します。vの型がlong doubleの場合は、長さ修飾子Lが変換指定子に追加されます。- さらに、
floatfield != (ios_base::fixed | ios_base::scientific)の場合は (C++11以上)、str.precision()に設定された精度修飾子が追加されます。
- 整数型と浮動小数点型の場合、
showposがセットされていれば、修飾子+が前置されます。 - 整数型の場合、
showbaseがセットされていれば、修飾子#が前置されます。 - 浮動小数点型の場合、
showpointがセットされていれば、修飾子#が前置されます。 vの型がvoid*の場合は、変換指定子%pを使用します。- "C" ロケールで
std::printf(spec, v)(ただしspecは選択された変換指定子) を呼んだかのように、ナロー文字列が作成されます。
ステージ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()によって置き換えられます。
ステージ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()より小さい場合、シーケンスの長さをstr.width()にするため、パディングの示す位置にfill文字のコピーが挿入されます。
いずれの場合でも、 std::setw の効果を取り消すために str.width(0) が呼ばれます。
ステージ4: 出力
ステージ3からの CharT のシーケンスからのすべての連続する文字 c が、 *out++ = c によって行われたかのように、出力されます。
引数
| out | - | 上書きされる最初の文字を指すイテレータ |
| str | - | 書式化情報を取得するストリーム |
| fill | - | 結果をフィールド幅にパディングする必要があるときに使用するパディング文字 |
| v | - | 文字列に変換して出力する値 |
戻り値
out。
ノート
先行するゼロは変換指定子 #o (例えば std::showbase と std::oct の組み合わせの結果) によって生成され、パディング文字としては数えられません。
浮動小数点値を hexfloat として書式化するとき (すなわち floatfield == (std::ios_base::fixed | std::ios_base::scientific) のとき)、ストリームの精度は使用されません。 代わりに、数値は常に、値を正確に表現するために十分な精度で表示されます。 |
(C++11以上) |
例
ファセットを直接使用して数値を出力し、ユーザ定義ファセットをデモンストレーションします。
Run this code
#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 s, std::ios_base& f,
char_type fill, long v) const
{
return std::num_put<char>::do_put(s, f, fill, v*v );
}
iter_type do_put(iter_type s, std::ios_base& f,
char_type fill, unsigned long v) const
{
return std::num_put<char>::do_put(s, f, fill, v*v);
}
};
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<< の実装。
Run this code
#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, base const& 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
関連項目
| 書式付きデータを挿入します ( std::basic_ostream<CharT,Traits>のパブリックメンバ関数)
|