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:
Copyright © 2000, Thinkage Ltd.