------- Introduction ---------------
The book "Programming: Principles and Practice using C++" [1] says on chapter 11:
"Terms such as hex and oct that are used to change the behavior of the stream are called manipulators."
An example:
#include <iostream>
using namespace std;
int main()
{
cout << hex << 1234 << endl;
return 0;
}
Manipulators change stream flags whose format is represented by the type fmtflags.
Here, we have a list with fmtflags:
basefield
oct
hex
dec
adjustfield
left
right
internal
floatfield
scientific
fixed
---------
boolalpha
showbase
showpoint
showpos
skipws
unitbuf
uppercase
from
http://en.cppreference.com/w/cpp/io/ios_base/fmtflags
A combination of flags determines how the stream behaves, moreover, such a combination can be more easily and correctly altered by manipulators.
You can see the relationship between the flags and the behavior by looking at the following tables (from C++11 specification [3] : § 22.4.2.1.2 and §
22.4.2.2.2).
1. Input
1.1 Integers
+------------------------+------------------+
| State | stdio equivalent |
+------------------------+------------------+
| basefield == oct | %o |
| basefield == hex | %X |
| basefield == 0 | %i | [2]
| signed integral type | %d |
| unsigned integral type | %u |
+------------------------+------------------+
1.2 Floating point
For conversions to a floating type the specifier is %g.
2. Output
2.1 Integers
+--------------------------------------------+------------------+
| State | stdio equivalent |
+--------------------------------------------+------------------+
| basefield == oct | %o |
| (basefield == ios_base::hex) && !uppercase | %x | [2]
| (basefield == ios_base::hex) | %X |
| for a signed integral type | %d |
| for an unsigned integral type | %u |
+--------------------------------------------+------------------++
2.2 Floating point
+----------------------------------------------------------------------+------------------+
| State | stdio equivalent |
+----------------------------------------------------------------------+------------------+
| floatfield == ios_base::fixed | %f |
| floatfield == ios_base::scientific && !uppercase | %e |
| floatfield == ios_base::scientific | %E | [2]
| floatfield == (ios_base::fixed | ios_base::scientific) && !uppercase | %a |
| floatfield == (ios_base::fixed | ios_base::scientific) | %A |
| !uppercase | %g |
| otherwise | %G |
+----------------------------------------------------------------------+------------------+
And you can see the relationship between the manipulators and the flags by looking at the following table (from C++11 specification [3] : § 27.5.6).
+--------------+------------------------------------------------------------------------------+
| Manipulator | Effect |
+--------------+------------------------------------------------------------------------------+
| boolalpha | Calls str.setf(ios_base::boolalpha) |
| noboolalpha | Calls str.unsetf(ios_base::boolalpha) |
| showbase | Calls str.setf(ios_base::showbase) |
| noshowbase | Calls str.unsetf(ios_base::showbase) |
| showpoint | Calls str.setf(ios_base::showpoint) |
| noshowpoint | Calls str.unsetf(ios_base::showpoint) |
| showpos | Calls str.setf(ios_base::showpos) |
| noshowpos | Calls str.unsetf(ios_base::showpos) |
| skipws | Calls str.setf(ios_base::skipws) |
| noskipws | Calls str.unsetf(ios_base::skipws) |
| uppercase | Calls str.setf(ios_base::uppercase) |
| nouppercase | Calls str.unsetf(ios_base::uppercase) |
| unitbuf | Calls str.setf(ios_base::unitbuf) |
| nounitbuf | Calls str.unsetf(ios_base::unitbuf) |
| internal | Calls str.setf(ios_base::internal, ios_base::adjustfield) |
| left | Calls str.setf(ios_base::left, ios_base::adjustfield) |
| right | Calls str.setf(ios_base::right, ios_base::adjustfield) |
| dec | Calls str.setf(ios_base::dec, ios_base::basefield) |
| hex | Calls str.setf(ios_base::hex, ios_base::basefield) |
| oct | Calls str.setf(ios_base::oct, ios_base::basefield) |
| fixed | Calls str.setf(ios_base::fixed, ios_base::floatfield) |
| scientific | Calls str.setf(ios_base::scientific, ios_base::floatfield) |
| hexfloat | Calls str.setf(ios_base::fixed | ios_base::scientific, ios_base::floatfield) |
| defaultfloat | Calls str.unsetf(ios_base::floatfield) |
+--------------+------------------------------------------------------------------------------+
------- The "Problem" ---------------
The book [1] on chapter 11 put a code similar to this:
#include<iostream>
#include<vector>
using namespace std;
int main()
{
cin.unsetf(ios_base::dec);
cin.unsetf(ios_base::oct);
cin.unsetf(ios_base::hex);
int x;
cin >> x;
cout << x;
return 0;
}
Or equivalent:
#include<iostream>
#include<vector>
using namespace std;
int main()
{
cin.unsetf(ios_base::basefield);
int x;
cin >> x;
cout << x << endl;
return 0;
}
Running this program:
$ CC a.cpp
$ ./a.out
10
10
$ ./a.out
0xa
10
$ ./a.out
012
10
$
The book says "You can get >> to accept and correctly interpret the 0 and 0x prefixes. To do that, you 'unset' all the defaults.".
And if you see the first table, then you can see that the "stdio equivalent" is %i, exactly as expected because this:
http://stackoverflow.com/questions/1893490/difference-between-format-specifiers-i-and-d-in-printf
The "problem" is:
All the "stdio equivalent" can be reached using manipulators, with one exception: %i,
which requires the programmer to write manually the flags
Would not it be more appropriate, from the point of view of orthogonality, that there was a manipulator to cover that particular case? (That is, the
case where basefield has to be 0).
-------------------------------------------------------------------------
[1]
http://www.stroustrup.com/programming.html / ISBN 978-0321-992789
[2] All tables are ordered. That is, the first line whose condition is true applies.
[3] ISO/IEC 14882:2011[E] Information technology — Programming languages — C++
Tables were generated by
https://ozh.github.io/ascii-tables/
I have the original books/standard. I quote some fair minimal excerpts for research purpose.