std::num_put::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; | | |
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; | | |
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; | | |
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; | | |
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
. - 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
If floatfield == (std::ios_base::fixed | std::ios_base::scientific) && !uppercase, will use conversion specifier %a If floatfield == (std::ios_base::fixed | std::ios_base::scientific), will use conversion specifier %A | (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()
- 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
operator<< | inserts formatted data (public member function of std::basic_ostream) |
---|
© cppreference.com
Licensed under the Creative Commons Attribution-ShareAlike Unported License v3.0.
本文档系腾讯云开发者社区成员共同维护,如有问题请联系 cloudcommunity@tencent.com