std::stringstream 中双重输出的默认格式标志(和宽度)是什么?

What are the default Format Flags (and widths) for double output in a std::stringstream?

当我将 double 写入 stringstream 时,默认格式是什么?

double v = 3.0;
std::stringstream ss;
ss << v;

在哪里可以找到 stringstream 的默认格式设置列表? std::istream 的所有派生 类(在标准库中)的默认格式是否相同?

默认值由 std::basic_ios::init 设置,并且对于从 ios_base 派生的所有流都是相同的。默认值是:

rdbuf()         sb
tie()           0
rdstate()       goodbit if sb is not a null pointer, otherwise badbit.
exceptions()    goodbit
flags()         skipws | dec
width()         0
precision()     6
fill()          widen(’ ’)
getloc()        a copy of the value returned by locale()
iarray          a null pointer
parray          a null pointer

所以默认精度为6

Where can I find a list of the default format setup for a stringstream?

所有标准库行为的权威来源是标准文档。在这种情况下,[basic.ios.members].

部分中标记为 basic_ios::init() effects 的 table
+--------------+--------------------------------------------------------+
|   Element    |                         Value                          |
+--------------+--------------------------------------------------------+
| rdbuf()      | sb                                                     |
| tie()        | 0                                                      |
| rdstate()    | goodbit if sb is not a null pointer, otherwise badbit. |
| exceptions() | goodbit                                                |
| flags()      | skipws | dec                                           |
| width()      | 0                                                      |
| precision()  | 6                                                      |
| fill()       | widen(’ ’)                                             |
| getloc()     | a copy of the value returned by locale()               |
| iarray       | a null pointer                                         |
| parray       | a null pointer                                         |
+--------------+--------------------------------------------------------+

格式化浮点数取决于 floatfield 标志,该标志在默认 flags() 中未设置。该行为在 [facet.num.put.virtuals].

部分的 table Floating-point conversions 中定义
+----------------------------------------------------------------------+-----------------+
|                                State                                 | stdioequivalent |
+----------------------------------------------------------------------+-----------------+
| floatfield == ios_base::fixed                                        | %f              |
| floatfield == ios_base::scientific && !uppercase                     | %e              |
| floatfield == ios_base::scientific                                   | %E              |
| floatfield == (ios_base::fixed | ios_base::scientific) && !uppercase | %a              |
| floatfield == (ios_base::fixed | ios_base::scientific)               | %A              |
| !uppercase                                                           | %g              |
| otherwise                                                            | %G              |
+----------------------------------------------------------------------+-----------------+

因此,初始状态下的格式化应该匹配 stdio 格式标志 %G。 stdio 格式标志在 [Formatted input/output functions]:

部分的 C 标准中指定

f,F

A double argument representing a floating-point number is converted to decimal notation in style [−]ddd.ddd, where the number of digits after the decimal-point character is equal to the precision specification. If the precision is missing, it is taken as 6; if the precision is zero and the # flag is not specified, no decimal-point character appears. If a decimal-point character appears, at least one digit appears before it. The value is rounded to the appropriate number of digits.

e,E

A double argument representing a floating-point number is converted in the style [-]d.ddde±dd, where there is one digit (which is nonzero if the argument is nonzero) before the decimal-point character and the number of digits after it is equal to the precision; if the precision is missing, it is taken as 6; if the precision is zero and the # flag is not specified, no decimal-point character appears. The value is rounded to the appropriate number of digits. The E conversion specifier produces a number with E instead of e introducing the exponent. The exponent always contains at least two digits, and only as many more digits as necessary to represent the exponent. If the value is zero, the exponent is zero.

A double argument representing an infinity is converted in one of the styles [-]inf or [-]infinity - which style is implementation-defined. A double argument representing a NaN is converted in one of the styles [-]nan* or **[-nan](n-char-sequence) - which style, and the meaning of any n-char-sequence, is implementation-defined. The F conversion specifier produces INF,INFINITY, or NAN instead of inf,infinity ,or nan, respectively.

g,G

A double argument representing a floating-point number is converted in style f or e (or in style F or E in the case of G conversion specifier), depending on the value converted and the precision. Let P equal the precision if nonzero, 6 if the precision is omitted, or 1 if the precision is zero. Then, if a conversion with style E would have an exponent of X:

  • if P > X ≥ -4, the conversion is with style f (or F) and precision P - (X + 1).
  • otherwise, the conversion is with style e (or E) and precision P - 1.

Is the default format the same for all derived classes of std::istream (within the stdlib)?

是的,默认值是一样的。