std::num_put<CharT,OutputIt>::put, std::num_put<CharT,OutputIt>::do_put
Defined in header <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; | (since 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; | (since 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; | (since 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; | (since 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 member function, calls the protected virtual member function
do_put
of the most derived class.
2) Writes characters to the output sequence
out
which represent the value of v
, formatted as requested by the formatting flags str.flags()
and the std::numpunct
and std::ctype
facets of the locale imbued in the stream str
. This function is called by all formatted output stream operators, such as std::cout << n;
.Conversion occurs in four stages.
Stage 1: conversion specifier selection
- I/O format flags are obtained, as if by
-
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);
- If the type of
v
isbool
- If
boolalpha == 0
, then convertsv
to typeint
and performs integer output. - If
boolalpha != 0
obtainsstd::use_facet<std::numpunct<charT>>(str.getloc()).truename()
ifv == true
orstd::use_facet<std::numpunct<charT>>(str.getloc()).falsename()
ifv == false
, and outputs each successive characterc
of that string toout
with*out++ = c
. No further processing is done in this case, the function returnsout
.
- If
- If the type of
v
is an integer type, the the first applicable choice of the following is selected:
- If
basefield == oct
, will use conversion specifier%o
- If
basefield == hex && !uppercase
, will use conversion specifier%x
- If
basefield == hex
, will use conversion specifier%X
- If the type of
v
is signed, will use conversion specifier%d
- If the type of
v
is unsigned, will use conversion specifier%u
- For integer types, length modifier is added to the conversion specification if necessary:
l
forlong
andunsigned long
,ll
forlong long
andunsigned long long
(since C++11). - If the type of
v
is a floating-point type, the the first applicable choice of the following is selected:
- If
floatfield == std::ios_base::fixed
, will use conversion specifier%f
- If
floatfield == std::ios_base::scientific && !uppercase
, will use conversion specifier%e
- If
floatfield == std::ios_base::scientific
, will use conversion specifier%E
| (since C++11) |
- If
!uppercase
, will use conversion specifier%g
- otherwise, will use conversion specifier
%G
- If the type of
v
islong double
, the length modifierL
is added to the conversion specifier. - Additionally, if
floatfield != (ios_base::fixed | ios_base::scientific)
, then (since C++11) precision modifier is added, set tostr.precision()
- If the type of
- For both integer and floating-point types, if
showpos
is set, the modifier+
is prepended - For integer types, if
showbase
is set, the modifier#
is prepended. - For floating-point types, if
showpoint
is set, the modifier#
is prepended. - If the type of
v
isvoid*
, will use conversion specifier%p
- A narrow character string is created as if by a call to
std::printf(spec, v)
in the "C" locale, wherespec
is the chosen conversion specifier.
Stage 2: locale-specific conversion
- Every character
c
obtained in Stage 1, other than the decimal point'.'
, is converted toCharT
by callingstd::use_facet<std::ctype<CharT>>(str.getloc()).widen(c)
. - For arithmetic types, the thousands separator character, obtained from
std::use_facet<std::numpunct<CharT>>(str.getloc()).thousands_sep()
, is inserted into the sequence according to the grouping rules provided bystd::use_facet<std::numpunct<CharT>>(str.getloc()).grouping()
- Decimal point characters (
'.'
) are replaced bystd::use_facet<std::numpunct<CharT>>(str.getloc()).decimal_point()
Stage 3: padding
- The adjustment flag is obtained as if by
std::fmtflags adjustfield = (flags & (std::ios_base::adjustfield))
and examined to identify padding location, as follows
- If
adjustfield == std::ios_base::left
, will pad after - If
adjustfield == std::ios_base::right
, will pad before - If
adjustfield == std::ios_base::internal
and a sign character occurs in the representation, will pad after the sign - If
adjustfield == std::ios_base::internal
and Stage 1 representation began with 0x or 0X, will pad after the x or X - otherwise, will pad before
- If
str.width()
is non-zero (e.g.std::setw
was just used) and the number of CharT's after Stage 2 is less thanstr.width()
, then copies of thefill
character are inserted at the position indicated by padding to bring the length of the sequence tostr.width()
.
In any case, str.width(0)
is called to cancel the effects of std::setw
.
Stage 4: output
Every successive character c
from the sequence of CharT's from Stage 3 is output as if by *out++ = c
.
Parameters
out | - | iterator pointing to the first character to be overwritten |
str | - | stream to retrieve the formatting information from |
fill | - | padding character used when the results needs to be padded to the field width |
v | - | value to convert to string and output |
Return value
out
.
Notes
The leading zero generated by the conversion specification #o
(resulting from the combination of std::showbase
and std::oct
for example) is not counted as a padding character.
When formatting a floating point value as hexfloat (i.e., when floatfield == (std::ios_base::fixed | std::ios_base::scientific) ), the stream's precision is not used; instead, the number is always printed with enough precision to exactly represent the value. | (since C++11) |
Example
Output a number using the facet directly, and demonstrate user-defined 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 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'; }
Output:
2.71 36 144
An implementation of operator<<
for a user-defined type.
#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; }
Output:
10
See also
inserts formatted data (public member function of std::basic_ostream<CharT,Traits> ) |
© cppreference.com
Licensed under the Creative Commons Attribution-ShareAlike Unported License v3.0.
http://en.cppreference.com/w/cpp/locale/num_put/put