16.5: Formatted Output
(printf and friends)
C's venerable printf function,
which we've been using since day one,
prints or writes formatted output to the standard output.
As we've seen
(by example, if not formally),
printf's operation is controlled by its first,
``format'' argument,
which is either a simple string to be printed
or a string containing percent signs and other characters
which cause the formatted values of printf's other arguments
to be interspersed with the other text (if any) of the format string.
So far,
we've been using simple format specifiers
such as %d, %f, and %s.
But format specifiers can actually consist of several parts.
You can specify a ``field width'';
for example, %5d prints an integer in a field five characters wide,
padding the integer's value
with extra characters
if necessary
so that at least five characters are printed.
You can specify a ``precision'';
for example,
%.2f formats a floating-point number
with two digits printed after the decimal point.
You can also
add certain characters which
specify various options,
such as how a too-narrow field is to be padded out to its field width,
or what type of number you're printing.
For example, %-5d indicates that the padding characters
should be added after the field's value
(so that it's left-justified),
and %ld indicates that you're printing a long
instead of a plain int.
Formally, then,
the complete framework
for a printf format specifier
looks like
% flags width . precision modifier character
where all of the parts
except the % and the final
character
are optional.
The width gives the minimum overall width of the output
(the field)
generated by this format specifier.
If the output (the number of digits or characters)
would be less than the width,
it will be padded on the right
(or left, if the - flag is present),
usually with spaces.
If the output for the field ends up being larger than the specified width,
however, the field essentially overflows or grows;
the output is not truncated or anything.
That is, printf("%2d", 12345) prints 12345.
The precision is either:
- The number of digits printed after the decimal point,
for the floating-point formats %e, %f, and %g;
or
- The maximum number of characters to be printed,
for %s;
or
- The minimum number of digits to be printed,
for the integer formats %d, %o, %x, and %u.
For example,
printf("%.3s", "Hello, world!") prints Hel,
and
printf("%.5d", 12) prints 00012.
Either the width or the precision
(or both)
can be specified as *,
which indicates that the next int argument from the argument list
should be used as the field width or precision.
For example,
printf("%.*f", 2, 76.54321) prints 76.54.
The flags are a few optional characters
which modify the conversion in some way.
They are:
- ->
Force left adjustment,
by padding
(out to the field width)
on the right.
- 0>
Use 0 as the padding character,
instead of a space.
- space
For numeric formats,
if the converted number is positive,
leave an extra space before it
(so that it will line up with negative numbers if printed in columns).
- +>
Print positive numbers with a leading + sign.
- #>
Use an ``alternate form'' of the conversion.
(The details of the ``alternate forms'' are described below,
under the individual format characters.)
The modifier specifies the size of the corresponding argument:
l for long int,
h for short int,
L for long double.
Finally,
the
format character
controls the overall appearance of the conversion
(and,
along with the modifier,
specifies the type of the corresponding argument).
We've seen many of these already.
The complete list of format characters is:
- c>
Print a single character.
The corresponding argument is an int
(or,
by the default argument promotions,
a char or short int).
- d>
Print a decimal integer.
The corresponding argument is an int,
or a long int if the l modifier appears,
or a short int if the h modifier appears.
If the number is negative,
it is preceded by a -.
If the space flag appears and the number is positive,
it is preceded by a space.
If the + flag appears and the number is positive,
it is preceded by a +.
- e>
Print a floating-point number in scientific notation:
[-]m.nnnnnne[-]nn
.
The corresponding argument is
either a float or a double
or,
if the L modifier appears,
a long double.
The precision gives the number of places after the decimal point;
the default is 6.
If the # flag appears,
a decimal point will be printed even if the precision is 0.
- E>
Like e,
but use a capital E to set off the exponent.
- f>
Print a floating-point decimal number
(mmm.nnnnnn).
The corresponding argument is either
a float or a double
or,
if the L modifier appears,
a long double.
The precision gives the number of places after the decimal point;
the default is 6.
If the # flag appears,
a decimal point will be printed even if the precision is 0.
- g>
Use either e or f,
whichever works best given the range and precision of the number.
(Roughly speaking,
``works best'' means
to
display the most precision in the least space.)
If the # flag appears,
don't strip trailing 0's.
- G>
Like g,
but use E instead of e.
- i>
Just like d.
- n>
The corresponding argument is an int *.
Rather than printing anything,
%n stores the number of characters printed so far
(by this call to printf)
into the integer pointed to by the corresponding argument.
For example, if the variable np is an int,
printf("%s %n%s!", "Hello", &n, "world")
stores 6 into np.
- o>
Print an unsigned integer, in octal (base 8).
The corresponding argument is an unsigned int,
or an unsigned long int if the l modifier appears,
or an unsigned short int if the h modifier appears.
If the # flag appears,
and the number is nonzero,
it will be preceded by an extra 0,
to make it look like a C octal constant.
- p>
Print a pointer value
(the pointer, not what it points to),
in some implementation-defined format.
The corresponding argument is a void *.
Usually, the value printed
is the numeric value of the pointer--that is,
the memory address pointed to--in
hexadecimal.
For the segmented architecture of the IBM PC,
pointers are often printed using a segment:offset notation.
- s>
Print a string.
The corresponding argument is a char *
(which may result from an array of char).
If the optional precision is present,
at most that many characters of the string will be printed
(if the \0 isn't encountered first).
- u>
Print an unsigned decimal integer.
The corresponding argument is an unsigned int,
or an unsigned long int if the l modifier appears,
or an unsigned short int
if the h modifier appears.
- x>
Print an unsigned integer, in hexadecimal (base 16).
The corresponding argument is an unsigned int,
or an unsigned long int if the l modifier appears,
or an unsigned short int if the h modifier appears.
If the # flag appears,
and the number is nonzero,
it will be preceded by the characters 0x,
to make it look like a C hexadecimal constant.
- X>
Like x,
except that the capital letters
A, B, C, D, E, and F
are used for the hexadecimal digits 10-15.
(Also, the # flag leads to a leading 0X.)
- %>
Print a single % sign.
There is no corresponding argument.
When you want to print to an arbitrary stream,
instead of standard output,
just use fprintf,
which takes a leading FILE * argument:
fprintf(stderr, "Syntax error on line %d\n", lineno);
Sometimes,
it's useful to do some printf-like formatting,
but not output the string right away.
The sprintf function is a printf variant
which ``prints'' to an in-memory string
rather than to a FILE * stream.
For example,
one way to convert an integer to a string
(the opposite of atoi)
is:
int i = 123;
char string[20];
sprintf(string, "%d", i);
One thing to be careful of with sprintf,
though,
is that it's up to you
to make sure that the destination string
is big enough.
Read sequentially:
prev
next
up
top
This page by Steve Summit
// Copyright 1996-1999
// mail feedback