man page pass, minor cleanups
[unix-history] / usr / src / lib / libc / stdio / printf.3
index d1beb04..1daf8bc 100644 (file)
@@ -1,22 +1,29 @@
-.\"    @(#)printf.3    6.4 (Berkeley) %G%
+.\" Copyright (c) 1990 The Regents of the University of California.
+.\" All rights reserved.
 .\"
 .\"
-.TH PRINTF 3S ""
-.AT 3
+.\" This code is derived from software contributed to Berkeley by
+.\" Chris Torek.
+.\"
+.\" %sccs.include.redist.man%
+.\"
+.\"    @(#)printf.3    6.9 (Berkeley) %G%
+.\"
+.TH PRINTF 3 ""
+.UC 7
 .SH NAME
 .SH NAME
-printf, fprintf, sprintf \- formatted output conversion
+printf, fprintf, sprintf, snprintf, vprintf, vfprintf,
+vsprintf, vsnprintf \- formatted output conversion
 .SH SYNOPSIS
 .B #include <stdio.h>
 .PP
 .B printf(format
 .SH SYNOPSIS
 .B #include <stdio.h>
 .PP
 .B printf(format
-.RB [ ,
-arg ] ...
+[ , arg ... ]
 .B )
 .br
 .B char *format;
 .PP
 .B fprintf(stream, format
 .B )
 .br
 .B char *format;
 .PP
 .B fprintf(stream, format
-.RB [ ,
-arg ] ...
+[ , arg ... ]
 .B )
 .br
 .SM
 .B )
 .br
 .SM
@@ -25,74 +32,190 @@ arg ] ...
 .br
 .B char *format;
 .PP
 .br
 .B char *format;
 .PP
-.B sprintf(s, format
-.RB [ ,
-arg ] ...
+.B sprintf(str, format
+[ , arg ... ]
 .B )
 .br
 .B )
 .br
-.B char *s, format;
+.B char *str, *format;
+.PP
+.B snprintf(str, size, format
+[ , arg ... ]
+.B )
+.br
+.B char *str;
+.br
+.B size_t size;
+.br
+.B char *format;
+.\" .PP
+.\" .B char *smprintf(format
+.\" [ , arg ... ]
+.\" .B )
 .PP
 .B #include <varargs.h>
 .PP
 .B #include <varargs.h>
+.PP
+.B vprintf(format, ap)
 .br
 .br
-.B _doprnt(format, args, stream)
+.B char *format;
+.br
+.B va_list ap;
+.PP
+.B vfprintf(stream, format, ap)
+.br
+.SM
+.B FILE
+.B *stream;
 .br
 .B char *format;
 .br
 .br
 .B char *format;
 .br
-.B va_list *args;
+.B va_list ap;
+.PP
+.B vsprintf(str, format, ap)
+.br
+.B char *str, *format;
+.br
+.B va_list ap;
+.PP
+.B vsnprintf(str, size, format, ap)
+.br
+.B char *str;
+.br
+.B size_t size;
+.br
+.B char *format;
 .br
 .br
-.B FILE *stream;
+.B va_list ap;
+.\" .PP
+.\" .B char *vsmprintf(format, ap)
+.\" .br
+.\" .B char *format;
+.\" .br
+.\" .B va_list ap;
 .SH DESCRIPTION
 .SH DESCRIPTION
+The
+.I printf
+family of functions produces output according to a
+.I format
+as described below.
 .I Printf
 .I Printf
-places output on the standard output stream
-.BR stdout .
-.I Fprintf
-places output on the named output
-.IR stream .
+and
+.I vprintf
+write the standard output stream
+.BR stdout ;
+.I fprintf
+and
+.I vfprintf
+write the named output
+.IR stream ;
+.IR sprintf ,
+.IR snprintf ,
+.IR vsprintf ,
+and
+.I vsnprintf
+write to the character string
+.IR str .
+.\" .IR str ;
+.\" and
+.\" .I smprintf
+.\" and
+.\" .I vsmprintf
+.\" dynamically allocate a new string with
+.\" .IR malloc .
+Each function converts, formats, and prints the arguments following the
+.I format
+(or accessed via the variable-length argument facilities of
+.IR varargs (3))
+under control of the
+.I format
+argument.
+.\" Except for
+.\" .I smprintf
+.\" and
+.\" .IR vsmprintf ,
+.\" all of these functions return
+Each function returns
+the number of characters printed
+(not including the trailing `\e0' used to end output to strings).
+.\" .I Smprintf
+.\" and
+.\" .I vsmprintf
+.\" return a pointer to a string of an appropriate length;
+.\" this pointer should be passed to
+.\" .I free
+.\" to release the associated storage
+.\" when it is no longer needed.
+.\" If sufficient space is not avaliable,
+.\" .I smprintf
+.\" and
+.\" .I vsmprintf
+.\" will return
+.\" .SM
+.\" .BR NULL .
+.I Snprintf
+and
+.I vsnprintf
+will write at most
+.IR size \-1
+of the characters printed into the output string
+(the
+.IR size 'th
+character then gets the terminating `\e0');
+if the return value is greater than or equal to the
+.I size
+argument, the string was too short
+and some of the printed characters were discarded.
 .I Sprintf
 .I Sprintf
-places `output' in the string
-.IR s ,
-followed by the character `\\0'.
-All of these routines work by calling the internal
-routine
-.B _doprnt,
-using the variable-length argument facilities of
-.IR varargs (3).
+and
+.I vsprintf
+effectively assume an infinte
+.IR size .
 .PP
 .PP
-Each of these functions converts, formats, and prints its arguments after
-the first under control of the first argument.
-The first argument is a character string which contains two types of objects:
+The format is a string comprised of two types of objects:
 plain characters, which are simply copied to the output stream,
 plain characters, which are simply copied to the output stream,
-and conversion specifications, each of which causes conversion and printing
-of the next successive
-.I arg
-.IR printf .
-.PP
-Each conversion specification is introduced by the character
-.BR % .
-The remainder of the conversion specification includes
-in the following order
-.TP
+and conversion specifications,
+each of which causes conversion and printing of the next successive
+.IR arg .
+These arguments must correspond properly (after type promotion)
+with the conversion specifier.
+Each conversion is introduced by the
+.B %
+(percent sign) character.
+The rest of the conversion includes, in the following order,
+.TP 4
 .B \(bu
 .B \(bu
-Zero or more of following flags:
+Zero or more of the following flags:
 .RS
 .RS
-.TP
+.TP 4
 .B \(bu
 a `#' character
 specifying that the value should be converted to an ``alternate form''.
 For 
 .BR c ,
 .BR d ,
 .B \(bu
 a `#' character
 specifying that the value should be converted to an ``alternate form''.
 For 
 .BR c ,
 .BR d ,
+.BR i ,
+.BR n ,
+.BR p ,
 .BR s ,
 and
 .BR u ,
 .BR s ,
 and
 .BR u ,
-conversions, this option has no effect.  For 
+conversions, this option has no effect.
+For 
 .B o
 conversions, the precision of the number is increased to force the first
 .B o
 conversions, the precision of the number is increased to force the first
-character of the output string to a zero.  For 
-.BR x ( X )
-conversion, a non-zero result has the string 
-.BR 0x ( 0X )
-prepended to it.  For 
+character of the output string to a zero (except if a zero value is printed
+with an explicit precision of zero).
+For
+.B x
+and
+.B X
+conversions, a non-zero result has the string
+.B 0x
+(or
+.B 0X
+for
+.B X
+conversions) prepended to it.
+For
 .BR e ,
 .BR E ,
 .BR f ,
 .BR e ,
 .BR E ,
 .BR f ,
@@ -100,155 +223,284 @@ prepended to it.  For
 and
 .BR G ,
 conversions, the result will always contain a decimal point, even if no
 and
 .BR G ,
 conversions, the result will always contain a decimal point, even if no
-digits follow the point (normally, a decimal point only appears in the
-results of those conversions if a digit follows the decimal point).  For
+digits follow it (normally, a decimal point appears in the results of
+those conversions only if a digit follows).
+For
 .B g
 and
 .B G
 conversions, trailing zeros are not removed from the result as they
 would otherwise be.
 .B g
 and
 .B G
 conversions, trailing zeros are not removed from the result as they
 would otherwise be.
-.TP
+.TP 4
 .B \(bu
 .B \(bu
-a minus sign `\-' which specifies
-.I "left adjustment"
-of the converted value in the indicated field;
-.TP
+A zero `0' character specifying zero padding.
+For all conversions except
+.BR n ,
+the converted value is padded on the left with zeros rather than blanks.
+If a precision is given with a numeric conversion
+.RB ( d ,
+.BR i ,
+.BR o ,
+.BR u ,
+.BR i ,
+.BR x ,
+and
+.BR X ),
+the `0' flag is ignored.
+.TP 4
+.B \(bu
+A minus sign (`-') specifying left adjustment of the converted value
+in the indicated field.
+Except for
+.B n
+conversions, the converted value is padded on the right with blanks,
+rather than on the left with blanks or zeros.
+A `-' overrides a `0' if both are given.
+.TP 4
 .B \(bu
 .B \(bu
-a `+' character specifying that there should always be
-a sign placed before the number when using signed conversions.
-.TP
+A space, specifying that a blank should be left before a positive number
+produced by a signed conversion
+.RB ( d ,
+.BR e ,
+.BR E ,
+.BR f ,
+.BR g ,
+.BR G ,
+or
+.BR i ).
+.TP 4
 .B \(bu
 .B \(bu
-a space specifying that a blank should be left before a positive number
-during a signed conversion.  A `+' overrides a space if both are used.
+a `+' character specifying that a sign always be placed before a
+number produced by a signed conversion.
+A `+' overrides a space if both are used.
 .RE
 .RE
-.TP
+.TP 4
 .B \(bu
 .B \(bu
-an optional digit string specifying a
-.I "field width;"
-if the converted value has fewer characters than the field width
-it will be blank-padded on the left (or right,
-if the left-adjustment indicator has been given) to make up the field width;
-if the field width begins with a zero,
-zero-padding will be done instead of blank-padding;
-.TP
+An optional digit string specifying a field width.
+If the converted value has fewer characters than the field width, it will
+be padded on the left (or right, if the left-adjustment flag is used) to
+make up the field width.
+.TP 4
 .B \(bu
 .B \(bu
-an optional period
-.RB ` . '
-which serves to separate the field width from the next digit string;
-.TP
+An optional precision, in the form of a period (`.') followed by an
+optional digit string.  If the digit string is omitted, the precision
+is taken as zero.  This gives the minimum number of digits to appear for
+.BR d ,
+.BR i ,
+.BR o ,
+.BR u ,
+.BR x ,
+and
+.B X
+conversions, the number of digits to appear after the decimal point for
+.BR e ,
+.BR E ,
+and
+.B f
+conversions, the maximum number of significant digits for
+.B g
+and
+.B G
+conversions, or the maximum number of characters to be printed from a
+string for
+.B s
+conversions.
+.TP 4
 .B \(bu
 .B \(bu
-an optional digit string specifying a
-.I precision
-which specifies the number of digits to appear after the
-decimal point, for e- and f-conversion, or the maximum number of characters
-to be printed from a string;
-.TP
+The character
+.BR h ,
+specifying that a following
+.BR d ,
+.BR i ,
+.BR o ,
+.BR u ,
+.BR x ,
+or
+.B X
+conversion corresponds to a
+.B "short int"
+or
+.B "unsigned short int"
+argument, or that a following
+.B n
+conversion corresponds to a pointer to a
+.B "short int"
+argument.
+.TP 4
 .B \(bu
 the character
 .B l
 .B \(bu
 the character
 .B l
-specifying that a following
+(ell) specifying that a following
 .BR d ,
 .BR d ,
+.BR i ,
 .BR o ,
 .BR o ,
+.BR u ,
 .BR x ,
 or
 .BR x ,
 or
-.B u
-corresponds to a long integer
-.IR arg .
-.TP
+.B X
+conversion corresponds to a
+.B "long int"
+or
+.B "unsigned long int"
+argument, or that a following
+.B n
+conversion corresponds to a pointer to a
+.B "long int"
+argument.
+.TP 4
+.B \(bu
+The character
+.B L
+specifying that a following
+.BR e ,
+.BR E ,
+.BR f ,
+.BR g ,
+or
+.B G
+conversion corresponds to a
+.B "long double"
+argument (but note that long double values are not currently supported
+by the \s-2VAX\s0 and Tahoe compilers).
+.TP 4
 .B \(bu
 .B \(bu
-a character which indicates the type of
-conversion to be applied.
+A character which indicates the type of conversion to be applied.
 .PP
 .PP
-A field width or precision may be `*' instead of a digit string.
-In this case an integer
-.I arg
-supplies
-the field width or precision.
+A field width or precision may be an asterisk (`*') instead of a
+digit string.
+In this case an
+.B int
+argument supplies the value.
+A negative field width is treated as a left adjustment flag followed by a
+positive field width; a negative precision is treated as though it were
+missing.
 .PP
 .PP
-The conversion characters
-and their meanings are
-.TP
-.B dox
-The integer
-.I arg
-is converted to decimal, octal, or
-hexadecimal notation respectively.
-.TP
-.B f
-The float or double
-.I arg
-is converted to decimal notation
-in the style `[\fB\-\fR]ddd.ddd'
-where the number of d's after the decimal point
-is equal to the precision specification
+The conversion characters and their meanings are:
+.TP 4
+.B diouxX
+The
+.B int
+(or appropriate variant) argument is converted to signed decimal
+.RB ( d " and " i ),
+unsigned octal
+.RB ( o ),
+unsigned decimal
+.RB ( u ),
+or unsigned hexadecimal
+.RB ( x " and " X )
+notation respectively.  The letters
+.B abcdef
+are used for
+.B x
+conversions; the letters
+.B ABCDEF
+are used for
+.B X
+conversions.
+The precision, if any, gives the minimum number of digits that must
+appear; if the converted value requires fewer digits, it is padded on
+the left with zeros.
+.TP 4
+.B DOU
+The
+.B "long int"
+argument is converted to signed decimal, unsigned octal, or unsigned
+decimal, as if the format had been
+.BR ld ,
+.BR lo ,
+or
+.B lu
+respectively.
+These conversion characters are deprecated, and will eventually disappear.
+.TP 4
+.B eE
+The
+.B double
+argument is rounded and converted in the style
+`[\fB\-\fR]d\fB.\fRddd\fBe\fR\(+-dd' where there is one digit before the
+decimal point and the number after is equal to the precision specification
 for the argument.
 for the argument.
-If the precision
-is missing,
-6 digits are given;
-if the precision is explicitly 0, no digits and
-no decimal point are printed.
-.TP
-.B e
-The float or double
-.I arg
-is converted in the style
-`[\fB\-\fR]d\fB.\fRddd\fBe\fR\(+-dd'
-where there is one digit before the decimal point and
-the number after is equal to the
-precision specification for the argument;
-when the precision is missing,
-6 digits are produced.
-.TP
+If the precision is missing, 6 digits are given; if the precision is
+explicitly zero, no decimal point appears.
+An
+.B E
+conversion uses the letter
+.B E
+(rather than
+.BR e )
+to introduce the exponent.
+The exponent always contains at least two digits; if the value is zero,
+the exponent is 00.
+.TP 4
+.B f
+The
+.B double
+argument is rounded and converted to decimal notation in the style
+`[\fB\-\fR]ddd.ddd' where the number of digits after the decimal point
+is equal to the precision.
+If the precision is missing, 6 digits are given; if the precision is
+explicitly 0, no digits and no decimal point are printed.
+If a decimal point appears, at least one digit appears before it.
+.TP 4
 .B g
 .B g
-The float or double
-.I arg
-is printed in style
-.BR d ,
-in style
-.BR f ,
-or in
-style
-.BR e ,
-whichever gives full precision in minimum space.
-.TP
+The
+.B double
+argument is printed in style
+.B f
+or
+.B e
+(or
+.B E
+for
+.B G
+conversions).
+The precision specifies the number of significant digits.
+If the precision is missing, 6 digits are given; if the precision is zero,
+it is treated as 1.
+Style
+.B e
+is used if the exponent from its conversion is less than -4 or greater than
+or equal to the precision.
+Trailing zeros are removed from the fractional part of the result; a
+decimal point appears only if it is followed by at least one digit.
+.TP 4
 .B c
 .B c
-The character
-.I arg
-is printed.
-.TP
+The
+.B int
+argument is converted to an
+.B "unsigned char",
+and the resulting character is printed.
+.TP 4
 .B s
 .B s
-.I Arg
-is taken to be a string (character pointer)
-and characters from the string are printed until
-a null character or until
-the number of characters indicated by the precision
-specification is reached;
-however if the precision is 0 or missing
-all characters up to a null are printed.
-.TP
-.B u
-The unsigned integer
-.I arg
-is converted to decimal
-and printed (the result will be in the
-range 0 through MAXUINT, where MAXUINT equals 4294967295 on a VAX-11
-and 65535 on a PDP-11).
-.TP
+The
+.B "char *"
+argument is taken to be a string (character pointer).
+Characters from the string are printed until a null character is reached,
+or until the number of characters indicated by the precision have been
+printed, whichever occurs first; if a precision is given, no null character
+need be present.
+.TP 4
+.B p
+The
+.B "void *"
+pointer argument is printed in hexadecimal (as if by `%#x' or `%#lx').
+.TP 4
+.B n
+The number of characters written so far is stored into the
+integer indicated by the
+.B "int *"
+(or variant) pointer argument.
+No argument is converted.
+.TP 4
 .B %
 .B %
-Print a `%'; no argument is converted.
+Prints a `%'; no argument is converted.
 .PP
 .PP
-In no case does a non-existent or small field width
-cause truncation of a field;
-padding takes place only if the specified field
-width exceeds the actual width.
-Characters generated by
-.I printf
-are printed by 
-.IR putc (3S).
+In no case does a non-existent or small field width cause truncation of
+a field; if the result of a conversion is wider than the field width, the
+field is expanded to contain it.
+Similarly, padding takes place only if the specified field width exceeds
+the actual width.
 .PP
 .PP
-.SH "RETURN VALUE"
-The functions \fIprintf\fP, \fIfprintf\fP, and \fIsprintf\fP return
-the number of characters printf, or -1 if an error occurred.
 .SH EXAMPLES
 .br
 To print a date and time in the form `Sunday, July 3, 10:02',
 .SH EXAMPLES
 .br
 To print a date and time in the form `Sunday, July 3, 10:02',
@@ -260,7 +512,7 @@ are pointers to null-terminated strings:
 .RS
 .HP
 .nh
 .RS
 .HP
 .nh
-printf("%s, %s %d, %02d:%02d", weekday, month, day, hour, min);
+printf("%s, %s %d, %02d:%.2d", weekday, month, day, hour, min);
 .RE
 .hy
 .PP
 .RE
 .hy
 .PP
@@ -270,9 +522,48 @@ To print
 to 5 decimals:
 .IP
 printf("pi = %.5f", 4*atan(1.0));
 to 5 decimals:
 .IP
 printf("pi = %.5f", 4*atan(1.0));
+.PP
+To allocate a 128 byte string and print into it:
+.RS
+.nf
+.ta 1i 2i
+.sp
+#include <stdio.h>
+#include <varargs.h>
+char *newfmt(va_alist)
+       va_dcl
+{
+       char *p, *malloc(), *fmt;
+       va_list ap;
+       if ((p = malloc(128)) == NULL)
+               return (NULL);
+       va_start(ap);
+       fmt = va_arg(ap, char *);
+       (void) vsprintf(p, fmt, ap);
+       va_end(ap);
+       return (p);
+}
+.RE
+.fi
 .SH "SEE ALSO"
 .SH "SEE ALSO"
-putc(3S),
-scanf(3S),
-ecvt(3)
+printf(1), scanf(3)
 .SH BUGS
 .SH BUGS
-Very wide fields (>128 characters) fail.
+The conversion formats `%D', `%O', and `%U' are not standard and
+are provided only for backward compatibility.
+The effect of padding the `%p' format with zeros (either by the `0'
+flag or by specifying a precision), and the benign effect (i.e., none)
+of the `#' flag on `%n' and `%p' conversions, as well as other
+nonsensical combinations such as `%Ld', are not standard; such combinations
+should be avoided.
+.PP
+Because
+.I sprintf
+and
+.I vsprintf
+assume an infinitely long string,
+callers must be careful not to overflow the actual space;
+this is often impossible to assure.
+For safety, programmers should use the
+.I snprintf
+interface instead.
+Unfortunately, this interface is not portable.