.TH printf() "" "" "STDIO Function (libc)"
.PC "Print formatted text"
.B "#include <stdio.h>"
\fBint printf(\fIformat \fB[,\fIarg1, .\^.\^.\^. argN\^\fB])\fR
\fBchar *\fIformat\^\fB;\fR \fB[data type] \fIarg1, .\^.\^. argN\^\fB;\fR
.PP
.II "standard output stream^print formatted text"
.II "text^print formatted into stream"
.B printf()
prints formatted text.
It uses the
.I format
string to specify an output format for each
.IR arg ,
which it then writes on the standard output.
.PP
.B printf()
reads characters from
.I format
one at a time; any character other than a percent sign \*(Ql%\*(Qr
or a string that is introduced with a percent sign is copied directly to
the output.
A \*(Ql%\*(Qr tells
.B printf()
that what follows specifies how the corresponding
.I arg
is to be formatted;
the characters that follow \*(Ql%\*(Qr
can set the output width and
the type of conversion desired.
The following modifiers, in this order, may precede the conversion type:
.IP \fB1.\fR 0.3i
A minus sign \*(Ql\-\*(Qr 
left-justifies the output field, instead of the default right justify.
.IP \fB2.\fR
A string of digits gives the
.I width
of the output field.
Normally,
.B printf()
pads the field with spaces to the field width;
it is padded on the left unless left justification is specified
with a \*(Ql\fB-\fR\*(Qr.
.IP
If the field width begins with \*(Ql0\*(Qr,
the field is padded with \*(Ql0\*(Qr characters instead of
spaces; the \*(Ql0\*(Qr does not cause the field
width to be taken as an octal number.
Note that this applies only to numeric string descriptors.
If the field descriptor describes a character or string
(i.e.,
.B %c
or
.BR %s ),
.B printf()
ignores a leading `0' and always pads the field with spaces.
.IP
If the width specification is an asterisk \*(Ql*\*(Qr,
the routine uses the next
.I arg
as an integer that gives the width of the field.
.IP \fB3.\fR
A period \*(Ql\fB.\fR\*(Qr followed by one or more digits gives the
.IR precision .
For floating point (\fBe\fR, \fBf\fR, and \fBg\fR) conversions,
the precision sets the number of digits printed after the decimal point.
For string (\fBs\fR) conversions, the precision sets the maximum number of
characters that can be used from the string.
If the precision specification is given as an asterisk \*(Ql*\*(Qr, 
the routine uses the next
.I arg
as an integer that gives the precision.
.IP \fB4.\fR
The letter \*(Ql\fBl\fR\*(Qr before any integer conversion (\fBd\fR, \fBo\fR,
\fBx\fR, or \fBu\fR) indicates that the argument is a
.B long
rather than an
.BR int .
Capitalizing the conversion type has the same effect; note, however,
that capitalized conversion types are
.I not
compatible with all C compiler libraries, or with the ANSI standard.
This feature will not be supported in future editions of \*(PN.
.PP
The following format conversions are recognized:
.IP \fB%\fR 0.3i
Print a \*(Ql%\*(Qr character.
No arguments are processed.
.IP \fBc\fR
Print the
.B int
argument as a character.
.IP \fBd\fR
Print the
.B int
argument as signed decimal numerals.
.\".IP \fBD\fR
.\"Print the
.\".B long
.\"argument as signed decimal numerals.
.IP \fBe\fR
Print the
.B float
or
.B double
argument in exponential form.
The format is \fId.dddddd\fBe\fIs\fR\fIdd\fR, where there is always one
digit before the decimal point and as many as the
.I precision
digits after it (default, six).
The exponent sign \fIs\fR may be either \*(Ql+\*(Qr or \*(Ql\-\*(Qr.
.IP \fBf\fR
Print the
.B float
or
.B double
argument as a string with an
optional leading minus sign \*(Ql\-\*(Qr, 
at least one decimal digit, a decimal point
(\*(Ql\fB.\fR\*(Qr), and optional decimal digits after the decimal point.
The number of digits after the decimal point is the
.I precision
(default, six).
.IP \fBg\fR
Print the
.B float
or
.B double
argument as whichever of the formats
.BR d ,
.BR e ,
or
.B f
loses no significant precision and takes the least space.
.IP \fBld\fR
Print the
.B long
argument as signed decimal numerals.
.IP \fBlo\fR
Print the
.B long
argument in unsigned octal numerals.
.IP \fBlu\fR
Print the
.B long
argument in unsigned decimal numerals.
.IP \fBlx\fR
Print the
.B long
argument in unsigned hexadecimal numerals.
.IP \fBo\fR
Print the
.B int
argument in unsigned octal numerals.
.\".IP \fBO\fR
.\"Print the
.\".B long
.\"argument in unsigned octal numerals.
.IP \fBp\fR
The ANSI standard states that the behavior of the \fB%p\fR descriptor is
implementation-specific.
Under \*(CO, \fB%p\fR prints in format
.B %#.8X
the literal value of a pointer.
Its corresponding variable must be of type \fBchar *\fR.
.IP \fBr\fR
The next argument points to an array of new arguments that may be used
recursively.
The first argument of the list is a \fBchar *\fR that contains a new format
string.
When the list is exhausted, the routine continues from where it left off in
the original format string.
.IP
This descriptor is not part of the \*(AS.
Its use is deprecated.
Code that uses it may not be portable to other systems.
.IP \fBs\fR
Print the string to which the \fBchar *\fR argument points.
Reaching either the end of the string, indicated by a null character, or the
specified
.IR precision ,
will terminate output.
If no
.I precision
is given, only the end of the string will terminate.
.IP \fBu\fR
Print the
.B int
argument in unsigned decimal numerals.
.\".IP \fBU\fR
.\"Print the
.\".B long
.\"argument in unsigned decimal numerals.
.IP \fBx\fR
Print the
.B int
argument in unsigned hexadecimal numerals.
The digits are prefaced by the string \fB0x\fR.
.IP \fBX\fR
Like
.BR %x ,
except that the digits are prefaced by the string \fB0X\fR.
Note \*(CO release 4.2 has changed the means of
.B %X
to conform to the ANSI C standard.
In versions prior to release 4.2, this format conversion printed a
.B long
argument in unsigned hexadecimal numerals.
Programs that depend upon the obsolete use of
.B %X
will no long work the same under the current release of \*(CO.
.PP
If it wrote the formatted string correctly,
.B printf()
returns the number of characters written.
Otherwise, it returns a negative number.
.SH Example
This example implements a mini-interpreter for
.B printf()
statements.
It is a convenient tool for seeing exactly how some of the
.B printf()
options work.
To use it, type a
.B printf()
conversion specification at the prompt.
The formatted string will then appear.
To reuse a format identifier, simply type
.BR <return> :
.DM
#include <math.h>
#include <stddef.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
.DE
.DM
/* the replies go here */
static char reply[80];
.DE
.DM
/* ask for a string and echo it in reply. */
char *askstr(msg)
char *msg;
{
	printf("Enter %s ", msg);
	fflush(stdout);
.DE
.DM
	if (gets(reply) == NULL)
		exit(EXIT_SUCCESS);
	return (reply);
}
.DE
.DM
main()
{
	char fid[80], c;
.DE
.DM
	/* initialize to an invalid format identifier */
	strcpy(fid, "%Z");
.DE
.DM
	for (;;) {
		askstr("format identifier");
		/* null reply uses previous FID */
		if (reply[0])
			/* leave the '%' */
			strcpy(fid + 1, reply);
.DE
.DM
		switch(c = fid[strlen(fid) - 1]) {
		case 'd':
		case 'i':
			askstr("signed number");
			if(strchr(fid, 'l') != NULL)
				printf(fid, atol(reply));
			else
				printf(fid, atoi(reply));
			break;
.DE
.DM
		case 'o':
		case 'u':
		case 'x':
		case 'X':
			askstr("unsigned number");
			if(strchr(fid, 'l') != NULL)
				printf(fid, atol(reply));
			else
				printf(fid, (unsigned)atol(reply));
			break;
.DE
.DM
		case 'f':
		case 'e':
		case 'E':
		case 'g':
		case 'G':
			printf(fid, atof(askstr("real number")));
			break;
.DE
.DM
		case 's':
			printf(fid, askstr("string"));
			break;
.DE
.DM
		case 'c':
			printf(fid, *askstr("single character"));
			break;
.DE
.DM
		case '%':
			printf(fid);
			break;
.DE
.DM
		case 'p':
			/* print pointer to format id */
			printf(fid, fid);
			break;
.DE
.DM
		case 'n':
			printf("n not implemented");
			break;
.DE
.DM
		default:
			printf("%c not valid", c);
		}
.DE
.DM
		printf("\en");
	}
}
.DE
.SH "See Also"
.Xr "ecvt()," ecvt
.Xr "fcvt()," fcvt
.Xr "fprintf()," fprintf
.Xr "gcvt()," gcvt
.Xr "libc," libc
.Xr "putc()," putc
.Xr "puts()," puts
.Xr "scanf()," scanf
.Xr "sprintf()," sprintf
.Xr "vprintf()" vprintf
.br
\*(AS, \(sc7.9.6.3
.br
\*(PX Standard, \(sc8.1
.SH Notes
Because C does not perform type checking,
it is essential that each argument match its
counterpart in the format string.
.PP
Versions of \*(CO prior to release 4.2 recognized the conversion formats
.BR %D ,
.BR %O ,
and
.BR %U .
The ANSI standard does not recognize these conversion characters, and
beginning with release 4.2 the
\*(CO implementation of
.B printf()
no longer recognizes them.
You should instead use, respectively, the conversion characters
.BR %ld ,
.BR %lo ,
and
.BR %lu .
