By default, an I/O stream performs text I/O, also known as formatted I/O, in which text is converted to and from numeric and other values. For output, values are converted to text, and padding, alignment, and other formatting is applied to the text. For input, formatting controls how text is converted to values and whether whitespace is skipped prior to reading an input field.
Different systems have different ways of representing the end of a
line. A text I/O stream hides these details and maps all line endings in
a file to the newline character ('\n
'). Thus, the number of characters read from
or written to a file might not match the actual file size. An
implementation might require a newline at the end of the last line of a
file.
To control formatting, a stream keeps track of a set of flags, a
field width, and a precision. Table 13-12 (in the <ios>
section) lists all the formatting
flags.
The formatted input functions are the overloaded operator>>
functions. If the skipws
flag is set (which is the default),
whitespace characters (according to the locale imbued in the stream)
are skipped, and input begins with the first non-whitespace
character.
If reading into a string
or
character array, all non-whitespace characters are read into the
string, ending with the first whitespace character or when width
characters have been read (if width
> 0), whichever comes first. The
width
is then reset to 0
.
For all other types, the width
is not used. To read a number from a
fixed-width field, read the field into a string, then use a string
stream to read the number, as shown in Example 9-2.
Example 9-2. Reading a number from a fixed-width field
template<typename T, typename charT, typename traits> std::basic_istream<charT, traits>& fixedread(std::basic_istream<charT, traits>& in, T& x) { if (in.width( ) == 0) // Not fixed size, so read normally. in >> x; else { std::string field; in >> field; std::basic_istringstream<charT, traits> stream(field); if (! (stream >> x)) in.setstate(std::ios_base::failbit); } return in; }
The only other flags that affect input are basefield
and boolalpha
:
The basefield
flag
determines how integers are interpreted. If basefield
is nonzero, it specifies a
fixed radix (oct
, hex
, or dec
), or if basefield
is 0
(the default), the input determines
the radix: leading 0x
or
0X
for hexadecimal, leading
0
for octal, decimal
otherwise.
If the boolalpha
flag is
set, a formatted read of bool
reads a string, which must match the names true
or false
(in the stream's locale, according
to the numpunct
facet). If the
boolalpha
flag is not set, a
bool
is read as a long integer,
and the number is converted to bool
using the standard rules: nonzero
is true
and 0
is false
. By default, the flag is clear
(false
).
Floating-point numbers are accepted in fixed or scientific format.
The decimal point character is determined by the stream's
locale, as is the thousands separator. Thousands separators are
optional in the input stream, but if present, they must match the
locale's thousands separator character and grouping rules. For
example, assuming that the thousands separator is , and the grouping
is for every 3 characters (grouping(
)
returns "\3
"), the
following are three valid input examples and one invalid
example:
1,234,567 // Valid 1,234,56 // Invalid 1234567 // Valid 1234,567 // Valid
When reading data that the user types, you should imbue the
input stream with the user's native locale (e.g., cin.imbue(locale(""))
). For input that is
being read from files or other sources that require portable data
formats, be sure to use the "C
", or
classic, locale (e.g., cin.imbue(locale::classic( ))
).
See the num_get
facet in the
<locale>
section of Chapter 13 for details on how numeric
input is parsed and interpreted.
The formatted output functions are the overloaded operator<<
functions. They all work
similarly, using the flags and other information to format a value as
a string. The string is then padded with zero or more copies of a
fill
character to achieve the
desired width
. The adjustfield
flags are used to determine
where the fill
characters are added
(to the left
, right
, or internal
, with internal
meaning after a sign or a leading
0x
or 0X
).
The padded string is written to the output stream, and the
stream's width
is reset to 0
. The width
is the only formatting parameter that
is reset. The flags, precision
, and
the fill
character are "sticky" and
persist until they are changed explicitly.
Formatting an integer depends on the basefield
(hex
, oct
,
or dec
), uppercase
(0X
for hexadecimal), showpos
(insert a +
for positive numbers), and showbase
(to insert a prefix of 0x
or 0X
for hexadecimal or 0
for octal)
flags. The defaults are decimal, lowercase, no positive sign, and no
base. If the locale's numpunct
facet specifies thousands grouping, thousands separators are inserted
at the specified positions.
Formatting a floating-point number depends on the floatfield
(fixed
, scientific
, or 0
for general), uppercase
(E
for exponent), showpoint
(insert decimal point even if not
needed), and showpos
(insert a
+
for positive numbers) flags. The
defaults are general, lowercase, no point unless needed, and no
positive sign.
If the boolalpha
flag is set,
bool
values are written as names
(e.g., true
or false
, or other strings, depending on the
locale). If boolalpha
is not set,
bool
values are written as integers
(described earlier). The default flag is clear (false
).
When writing output for a user's immediate consumption, you
should imbue the output stream with the user's native locale (e.g.,
cout.imbue(locale(""))
). For output
that is being written to files or other sources that require portable
data formats, be sure to use the "C
", or classic, locale (e.g., cout.imbue(locale::classic( ))
).
See the num_put
facet in the
<locale>
section of Chapter 13 for details on how numeric
output is formatted.