PRINTF - formatted output to standard output.
(ANSI Standard)
Usage:
#include <stdio.h>
Nout = printf(format[,arg1,arg2,...]);
Where:
- const char *format;
- tells how to format the various arguments (see below).
- arg1,arg2,...
- is a variable argument list of expressions whose values should be printed according to
the placeholders in the "format" string. If there are more placeholders than
supplied arguments, the result is undefined. If there are more arguments than
placeholders, the excess arguments are simply ignored.
- int Nout;
- is the number of characters "printf" actually printed out.
Description:
"printf" writes formatted output to "stdout". The result of
"printf" is the number of characters written. If a write error occurs,
"printf" returns a negative number.
The output is formatted according to the "format" string. This string may
contain two kinds of objects:
- ordinary characters which are simply copied to "stdout";
- placeholders, which tell "printf" how to format arguments in the variable
argument list.
Each placeholder starts with the character '%' and ends with one or two letters that
indicate what "type" of formatting is necessary. Between the '%' and the
"type" field may appear "modifiers", "width", and
"precision" fields. An ANSI placeholder has the form
%[modifiers][width][.precision]type
where square brackets indicate that a field is optional.
Because '%' has a special meaning to "printf", you must use two of them to
stand for a literal per cent character. For example, you would use
printf("We had 100%% attendance!\n");
to print out the line
We had 100% attendance!
The Type Field
Below we list the recognized "type" fields. Note that each "type"
requires that the output value associated with the placeholder have a particular data
type. Note also that the standard rules for passing arguments in a variable argument list
automatically convert "char" and "short" values to "int",
and "float" values to "double", so "char",
"short", and "float" arguments are not possible.
The following types are recognized by the ANSI standard and can therefore be expected
to be portable.
- a
- "double" argument is displayed in one of the following formats:
0xh.hhhhp+d
0xh.hhhhp-d
-0xh.hhhhp+d
-0xh.hhhhp-d
where the "h" characters are lower case hexadecimal digits. This gives a
hexadecimal representation of the floating point number, where the exponent
("+d" or "-d") is a decimal number giving a power of two.
The number of hexadecimal digits after the decimal point is equal to the precision. If
you do not specify a precision, the number of digits after the decimal point is sufficient
to give an exact representation of the value.
On GCOS8, the first bit of the "double" value is the sign bit. The next three
bits are used for the hex digit that comes before the decimal point. Since GCOS8 always
normalizes the floating point value, the first of these three bits is always turned on.
Therefore, the number before the decimal point will always be 4, 5, 6, or 7.
The exponent always contains at least one digit; it is longer if more digits are
required to express the exponent value. As a special case, the exponent for 0.0 is always
zero.
As an example of "%a" format, the floating point value 1.0 would be displayed
as
0x4.00p-2
- A
- is the same as "%a" except that hexadecimal digits are shown in upper case and
the number begins with "0X" instead of "0x".
- c
- "int" argument is converted to "unsigned char", and then output.
Note that this only writes a single character, even if the original "int" value
held more than one character.
- d
- "int" argument is output as a signed decimal integer. If the number is
positive, a '+' sign may or may not be output, depending on the value of the modifiers
field.
- e
- "double" argument is output in scientific notation
[-]m.nnnnnne+xx
with one digit before the decimal point. The default number of digits after the decimal
point is six, but this can be changed with a precision field. The "double" value
is rounded to the correct number of decimal places. The exponent always contains two
digits.
- E
- same as "%e" format, except that the 'E' will be in upper case instead of
lower.
- f
- "double" argument is output in conventional form, i.e.
[-]mmmm.nnnnnn
The default number of digits after the decimal point is six, but this can be changed
with a precision field. If a decimal point appears, at least one digit appears before it.
The "double" value is rounded to the correct number of decimal places.
- g
- "double" argument is output in scientific or standard format. Scientific
notation is only used if the exponent resulting from the conversion is less than -4 or
greater than the precision; otherwise standard representation is used. With scientific
notation, the 'e' to mark the exponent is in lower case. The precision is taken to mean
the number of significant digits required (not necessarily the number of decimal places).
Trailing zeros are removed from the result, and a decimal point only appears if it is
followed by a digit.
- G
- same as "%g" format, except that the 'E' to mark the exponent in scientific
notation is in upper case.
- i
- same as "%d".
- n
- "(int *)" argument is taken to point to integer. "printf" assigns
this integer the number of characters that have been written to the output stream so far
by this call to "printf". No output is written for this placeholder.
- o
- "int" argument is output as an unsigned integer written with octal digits.
This will not have a leading zero, unless the # "modifier" is used (see below).
- p
- corresponding argument is assumed to be "(const void *)" value. The value of
the pointer is converted to a sequence of printable characters in an
implementation-defined manner. SS mode C displays the value of the pointer as an octal
integer.
- s
- "(const char *)" argument is taken as pointer to ASCII string. Characters in
this string will be output until a '\0' character is found or the number of characters
indicated by the precision field has been printed.
- u
- "int" argument is output as an unsigned decimal integer.
- x
- "int" argument is output as an unsigned integer written with hexadecimal
digits, using the letters 'a' to 'f' for hex digits greater than 9. This will not have a
leading '0x' unless the # "modifier" is used (see below).
- X
- same as "%x" except that the letters 'A' to 'F' are used for hex digits
greater than 9.
- hd
- same as "%d" except that "int" argument is converted to
"short" before formatting and printing. Since "short" is the same as
"int" on GCOS8, this is the same as "%d".
- hi
- same as "%hd".
- ho
- same as "%o" except that the "int" argument is converted to
"unsigned short" before formatting and printing. Since "unsigned
short" is the same as "unsigned" on GCOS8, this is the same as
"%o".
- hu
- same as "%u" except that the "int" argument is converted to
"unsigned short" before formatting and printing. Since "unsigned
short" is the same as "unsigned" on GCOS8, this is the same as
"%u".
- hx
- same as "%x" except that the "int" argument is converted to
"unsigned short" before formatting and printing. Since "unsigned
short" is the same as "unsigned" on GCOS8, this is the same as
"%x".
- hX
- same as "%X" except that the "int" argument is converted to
"unsigned short" before formatting and printing. Since "unsigned
short" is the same as "unsigned" on GCOS8, this is the same as
"%X".
- hhd
- same as "%d" except that "int" argument is converted to "signed
char" before formatting and printing.
- hi
- same as "%hhd".
- ho
- same as "%o" except that the "int" argument is converted to
"unsigned char" before formatting and printing.
- hu
- same as "%u" except that the "int" argument is converted to
"unsigned char" before formatting and printing.
- hx
- same as "%x" except that the "int" argument is converted to
"unsigned char" before formatting and printing.
- hX
- same as "%X" except that the "int" argument is converted to
"unsigned char" before formatting and printing.
- ld
- same as "%d" except argument is "long" integer. Since
"long" is the same as "int" on GCOS8, this is the same as
"%d". However, the compiler will warn you if you specify "%ld" but
pass a normal "int", or specify "%d" but pass a "long".
Similar warnings are issued for all the other "%l" placeholders described below.
- li
- same as "%ld".
- lo
- same as "%o" except argument is "unsigned long" integer. Since
"unsigned long" is the same as "unsigned" on GCOS8, this is equivalent
to "%o".
- lu
- same as "%u" except argument is "unsigned long" integer. Since
"unsigned long" is the same as "unsigned" on GCOS8, this is equivalent
to "%u".
- lx
- same as "%x" except argument is "unsigned long" integer. Since
"unsigned long" is the same as "unsigned" on GCOS8, this is equivalent
to "%x".
- lX
- same as "%X" except argument is "unsigned long" integer. Since
"unsigned long" is the same as "unsigned" on GCOS8, this is equivalent
to "%X".
- Le
- same as "%e" except argument is "long double". Since "long
double" is the same as "double" on GCOS8, this is the same as
"%e".
- LE
- same as "%E" except argument is "long double". Since "long
double" is the same as "double" on GCOS8, this is the same as
"%E".
- Lf
- same as "%f" except argument is "long double". Since "long
double" is the same as "double" on GCOS8, this is the same as
"%f".
- Lg
- same as "%g" except argument is "long double". Since "long
double" is the same as "double" on GCOS8, this is the same as
"%g".
- LG
- same as "%G" except argument is "long double". Since "long
double" is the same as "double" on GCOS8, this is the same as
"%G".
In addition to the types recognized by the ANSI standard, this version of C supports a
number of extensions:
- _a
- accepts a "char *" string pointer as its corresponding argument. The string
will be printed in a manner that resembles strings in C source code: non-printable
characters will be printed as escape sequences. For example, a new-line character will be
printed as '\n'; a non-standard character will be printed as a blackslash followed by
three octal digits. The width gives the minimum number of characters in the output field;
the precision gives the number of characters to be printed from the string. If there is no
precision specified, the entire string is printed (up to but not including the terminating
'\0' character). If you specify the '#' modifier, double quotes will be printed to enclose
the output string. If you specify the '-' modifier, output will be left-justified;
otherwise, it will be right-justified. If you specify the '+' modifier, '\0' characters
will not be considered to be the end of the string; in this case, a precision must be
specified to tell "printf" how many characters to print.
- b
- same as the "%b" placeholder of the "printf" in the UW Tools
package. See "expl b lib printf". This is
supported for compatibility with previous versions of C. It should not be used, since
"%b" is reserved for future use by the ANSI standard.
- B
- same as the "%B" placeholder of the "printf" in the UW Tools
package. See "expl b lib printf". This is
supported for compatibility with previous versions of C.
- _c
- "int" argument is taken to contain BCD characters. These are output as their
ASCII equivalents; letters are output in lower case. If you specify a precision of zero,
PRINTF will strip off high order zeroes at the beginning of the argument word and
interpret the rest as BCD characters. If you specify a width, the precision is
automatically set to the same value. If you do not specify either a precision or width,
the default is "%6.0_c".
- _C
- is the same as "%_c", except that letters are output in upper case.
- _e
- "double" argument is output in scientific notation. This is almost like
"%e", except that the width field takes precedence over the precision. Thus if
the requested width is too small to provide the requested precision, a smaller precision
will be used.
- _E
- same as "%_e" format except that the 'E' for the exponent will be in upper
case instead of lower.
- _f
- "double" argument is output in "optimal" format. If the specified
width is sufficient to hold the value with the requested precision in standard format
(nnn.nnn), the value will be printed in standard format. If the width is not sufficient,
"printf" will use either standard format or scientific notation, whichever
provides the requested precision with the fewer characters. If no width or precision is
specified, the number will be output with the greatest available precision. If a width is
specified, but not a precision, the number will be rounded to the appropriate width. If
the fractional part of the number is zero, no zeros will be printed after the decimal
place. Thus there is a difference between
1.
1.000000
The first number is a true 1.0. The second is not 1.0, but has a fractional part that
is too small to show in the given precision. When scientific notation is used, the 'e' to
mark the exponent is in lower case.
- _F
- same as "%_f", except that when scientific notation is used, the 'E' to mark
the exponent is in upper case.
- _g
- same as "%_f" format, except that the precision is interpreted as the number
of significant digits, not the number of decimal places. This means that very small
numbers will be printed in scientific notation instead of rounded to a .000000 form. When
scientific notation is used, the 'e' to mark the exponent is in lower case.
- _G
- same as "%_g" format, except that when scientific notation is used, the 'E' to
mark the exponent is in upper case.
- _s
- "(void *)" argument is taken as a BCD pointer. See "expl nsc lib _bcdptr" for more on BCD pointers.
If only a width is specified, the string will be assumed to have that number of BCD
characters, and the corresponding ASCII characters are output (with letters in lower case
and trailing blanks removed). If a width and a precision field are specified, the
precision is taken to be the number of BCD characters in the string and the width is the
size of the output field. If no width is given, the default is six. Trailing blanks are
stripped, unless the '#' modifier is specified. By default, the output is right-justified;
if the modifier '-' is given, the output will be left-justified.
- _S
- same as "%_s" except that letters are output in upper case.
- _v
- has two corresponding arguments: a "const char *" format string in the same
format as a normal "printf" format string; and a "va_list" argument,
as declared in <stdarg.h>. The "va_list" argument is presumed to indicate
all or part of a variable argument list (i.e. the argument has been set up with
"va_start"). The arguments remaining in this variable argument list are
formatted and output according to the given format string. For more information on
variable argument lists, see "expl c include stdarg".
The Modifiers Field
The modifiers field consists of zero or more characters that indicate how output should
be padded (e.g. whether numbers are preceded by blanks or leading zeros), and whether or
not '+' or '-' signs are printed. Below we list the possible "modifier"
characters. - (minus) indicates that values should be left-justified in the output field.
The default action is to right-justify them. + (plus) is relevant only for signed numeric
output values and "%_a". This "modifier" character tells
"printf" to put a sign in front of the number, whether or not it is negative.
Thus negative numbers will be preceded by '-' while zero and positive numbers will be
preceded by '+'. The default is to add the sign only if the number is negative. See the
description of "%_a" for the effect of '+' with that
placeholder. (blank) is relevant only for signed numeric output values. This
"modifier" character tells "printf" to put a sign in front of numbers
only if they are negative. If the number is non-negative, "printf" will put in a
blank instead of a sign. The default is not to put a blank in front of non-negative
number. If both '+' and ' ' are specified as "modifier" characters, the '+'
overrides the ' '. # (sharp) is relevant only for some output types.
If "type" is 'o', all non-zero values will have a leading 0; normally, octal
output has no leading zero.
If "type" is 'x' or 'X', all non-zero values will have a leading 0x or 0X
respectively; normally, such prefixes are omitted.
If "type" is 'e', 'E' or 'f', "printf" will always print out a
decimal point (normally, the decimal point is omitted if the number has no fractional
part).
If "type" is '_f', trailing zeros are printed after a decimal point, even if
the fractional part of the number is zero.
If "type" is 'g' or 'G', "printf" will always print out a decimal
point and trailing zeros will not be removed; usually 'g' and 'G' remove trailing zeros.
If "type" is '_s' or '_S', trailing blanks are not trimmed.
If "type" is '_a', the output is enclosed in double quotes.
The Width Field
The width field is a non-negative decimal integer giving the minimum number of
characters to be printed. If the output value is shorter than the given width, it is
padded to the appropriate width by putting blanks on the right (or on the left, if the '-'
"modifier" character is specified).
With numeric placeholders, the number in the width field may have a leading 0. With
this, the output value will be expanded with zeros to give the number the specified width.
For example, with "%05d" the value -1 will be printed as "-0001".
The width field can also be the character '*', in which case "printf" will
take the next argument in the argument list and take that as the width value. For example,
printf("%*d",4,X);
prints the value of X with a width of 4. Note that the width value is obtained from the
argument list BEFORE the output value is obtained.
The width field specifies the MINIMUM number of characters to be output. If more
characters are needed, the output will be wider than width (unless the precision value
dictates otherwise).
The Precision Field
The precision field is a dot '.' followed by a non-negative decimal integer. Its
meaning depends on the "type" field as given below.
- If the "type" is 'd', 'o', 'u', 'x' or 'X', the precision number is the
smallest number of digits that may appear in the output value. If necessary, the number
will be padded on the left with leading zeros. If the precision number is 0 or the field
is just a '.' with no number following, an output value of 0 will result in no characters
being printed.
- If the "type" is 'e', 'E', or 'f', the precision number is the number of
digits printed after the decimal point. If the precision number is 0 or the field is just
a '.' with no number following, no decimal point is printed.
- If the "type" is 'g' or 'G', the precision number is the maximum number of
significant digits to be printed. If no precision field is specified, six significant
digits are printed.
- If the "type" is 's', the precision number gives the maximum number of
characters to be printed.
- If the "type" is an 'h', 'hh', 'l' or 'L' type, the precision field has the
same effect as it has for the type without the 'h', 'hh', 'l' or 'L'.
- If the "type" is '_e', '_E', '_f', or '_F', the precision number is the number
of digits printed after the decimal point. If no precision is specified, the width will
dictate the precision. If no width is specified either, the value will be printed to full
precision.
- If the "type" is '_g' or '_G', the precision is the maximum number of
significant digits to be printed. If no precision field is specified, all significant
digits are printed.
The precision field can also be the character '*', in which case "printf"
will take the next argument in the argument list and take that as the precision value. For
example,
printf("%*.*f",8,3,Y);
prints the value of Y with a width of 8 and a precision of 3.
Fill Characters
As a non-ANSI extension, all placeholders may specify a "fill character" by
putting ",F" in front of the type designator (where F is any character). In any
situation where "printf" would normally fill out a field with blanks, the fill
character will be used instead. For example, with
printf("%5,#d",20);
the output would be
###20
The "#" after the comma is used as a fill character.
As with width and precision, the fill field can also be the character '*', in which
case "printf" will take the next argument in the argument list and take that as
the fill value. For example,
printf("%,*d",'*',20);
will fill with asterisks. If you want to fill with asterisks, you have to take this
approach. A question mark '?' as the fill field has the same meaning as '*'.
Defaults
Below we list the defaults when width and/or precision fields are omitted.
"%1c" "%1.1d" "%11.6e" "%11.6E"
"%8.6f" "%1.6g" "%1.6G" "%1.1o"
"%0s" "%1.1x" "%1.1X" "%1.1ld"
"%1.1lo" "%1.1lx" "%1.1lX" "%6.6Le"
"%6.6LE" "%6.6Lf" "%6.6Lg" "%6.6LG"
Examples:
#include <stdio.h>
int i = 3, j = -1, k = 4;
char *s = "string";
float x = 3.14159265;
printf("j = %.*d, %.3s x = %10.*f",i,j,s,k,x);
/* prints: j = -001, str x = 3.1416 */
In the next examples, we use the letter 'b' to show where spaces are printed out. In
all cases, the value printed is the integer -1.
Format Output
%5d bbb-1
%05d -0001
%5.5d -00001 (precision requires 5 sig. digits)
%5,0d 000-1 (zero is fill character)
Notes:
The single segment C version of "printf" is the same as the
"printf" function in the UW Tools library. Therefore you do not have to worry
about programs that combine the B and C versions of "printf". If the
"format" string is passed as a B pointer (in the lower 18 bits of the word, with
zeroes in the upper half of the word), "printf" behaves like the UW Tools
function. Otherwise, it behaves like the C version of the function.
The "printf" function does almost no validity checking on the format string.
Therefore, if you specify an invalid format, you will probably get invalid output without
any diagnostic message. You may also get more serious errors (e.g. memory faults).
Most users will find that "%g" is the best format for printing out single
floating point numbers, since it tries to choose the most readable format. For columns of
floating point numbers, "%_f" is usually better than "%f" because
"%_f" makes more of an effort to provide the precise width requested (or as
close as possible to that width).
See Also:
expl c lib fprintf
expl c lib scanf
expl c lib sprintf
expl c lib vprintf
expl b lib printf
Copyright © 2000, Thinkage Ltd.