xref: /openbsd-src/lib/libc/stdio/printf.3 (revision 99fd087599a8791921855f21bd7e36130f39aadc)
1.\"	$OpenBSD: printf.3,v 1.84 2019/08/30 20:27:25 jmc Exp $
2.\"
3.\" Copyright (c) 1990, 1991, 1993
4.\"	The Regents of the University of California.  All rights reserved.
5.\"
6.\" This code is derived from software contributed to Berkeley by
7.\" Chris Torek and the American National Standards Committee X3,
8.\" on Information Processing Systems.
9.\"
10.\" Redistribution and use in source and binary forms, with or without
11.\" modification, are permitted provided that the following conditions
12.\" are met:
13.\" 1. Redistributions of source code must retain the above copyright
14.\"    notice, this list of conditions and the following disclaimer.
15.\" 2. Redistributions in binary form must reproduce the above copyright
16.\"    notice, this list of conditions and the following disclaimer in the
17.\"    documentation and/or other materials provided with the distribution.
18.\" 3. Neither the name of the University nor the names of its contributors
19.\"    may be used to endorse or promote products derived from this software
20.\"    without specific prior written permission.
21.\"
22.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
23.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
24.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
25.\" ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
26.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
27.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
28.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
29.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
30.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
31.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
32.\" SUCH DAMAGE.
33.\"
34.\"     @(#)printf.3	8.1 (Berkeley) 6/4/93
35.\"
36.Dd $Mdocdate: August 30 2019 $
37.Dt PRINTF 3
38.Os
39.Sh NAME
40.Nm printf ,
41.Nm fprintf ,
42.Nm sprintf ,
43.Nm snprintf ,
44.Nm asprintf ,
45.Nm dprintf ,
46.Nm vprintf ,
47.Nm vfprintf ,
48.Nm vsprintf ,
49.Nm vsnprintf ,
50.Nm vasprintf ,
51.Nm vdprintf
52.Nd formatted output conversion
53.Sh SYNOPSIS
54.In stdio.h
55.Ft int
56.Fn printf "const char *format" ...
57.Ft int
58.Fn fprintf "FILE *stream" "const char *format" ...
59.Ft int
60.Fn sprintf "char *str" "const char *format" ...
61.Ft int
62.Fn snprintf "char *str" "size_t size" "const char *format" ...
63.Ft int
64.Fn asprintf "char **ret" "const char *format" ...
65.Ft int
66.Fn dprintf "int fd" "const char * restrict format" ...
67.In stdarg.h
68.In stdio.h
69.Ft int
70.Fn vprintf "const char *format" "va_list ap"
71.Ft int
72.Fn vfprintf "FILE *stream" "const char *format" "va_list ap"
73.Ft int
74.Fn vsprintf "char *str" "const char *format" "va_list ap"
75.Ft int
76.Fn vsnprintf "char *str" "size_t size" "const char *format" "va_list ap"
77.Ft int
78.Fn vasprintf "char **ret" "const char *format" "va_list ap"
79.Ft int
80.Fn vdprintf "int fd" "const char * restrict format" "va_list ap"
81.Sh DESCRIPTION
82The
83.Fn printf
84family of functions produce output according to the given
85.Fa format
86as described below.
87This format may contain
88.Dq conversion specifiers ;
89the results of such conversions, if any, depend on the arguments
90following the
91.Fa format
92string.
93.Pp
94The
95.Fn printf
96and
97.Fn vprintf
98functions write output to the standard output stream,
99.Em stdout ;
100.Fn fprintf
101and
102.Fn vfprintf
103write output to the supplied stream pointer
104.Fa stream ;
105.Fn dprintf
106and
107.Fn vdprintf
108write output to the given file descriptor;
109.Fn sprintf ,
110.Fn snprintf ,
111.Fn vsprintf ,
112and
113.Fn vsnprintf
114write to the character string
115.Fa str ;
116.Fn asprintf
117and
118.Fn vasprintf
119write to a dynamically allocated string that is stored in
120.Fa ret .
121.Pp
122These functions write the output under the control of a
123.Fa format
124string that specifies how subsequent arguments
125(or arguments accessed via the variable-length argument facilities of
126.Xr va_start 3 )
127are converted for output.
128.Pp
129.Fn snprintf
130and
131.Fn vsnprintf
132write at most
133.Fa size Ns \-1
134characters to
135.Fa str ,
136followed by a terminating
137.Ql \e0 .
138If
139.Fa size
140is zero,
141no characters are written and
142.Fa str
143may be a
144.Dv NULL
145pointer.
146.Pp
147.Fn sprintf
148and
149.Fn vsprintf
150effectively assume an infinite
151.Fa size ;
152their use is not recommended.
153.Pp
154The format string is composed of zero or more directives:
155ordinary
156.\" multibyte
157characters (not
158.Cm % ) ,
159which are copied unchanged to the output stream,
160and conversion specifications, each of which results
161in fetching zero or more subsequent arguments.
162Each conversion specification is introduced by the character
163.Cm % .
164The arguments must correspond properly (after type promotion)
165with the conversion specifier.
166After the
167.Cm % ,
168the following appear in sequence:
169.Bl -bullet
170.It
171An optional field, consisting of a decimal digit string followed by a
172.Cm $
173specifying the next argument to access.
174If this field is not provided, the argument following the last
175argument accessed will be used.
176Arguments are numbered starting at
177.Cm 1 .
178.It
179Zero or more of the following flags:
180.Bl -hyphen
181.It
182A hash
183.Sq Cm #
184character
185specifying that the value should be converted to an
186.Dq alternate form .
187For
188.Cm o
189conversions, the precision of the number is increased to force the first
190character of the output string to a zero (except if a zero value is printed
191with an explicit precision of zero).
192For
193.Cm x
194and
195.Cm X
196conversions, a non-zero result has the string
197.Ql 0x
198(or
199.Ql 0X
200for
201.Cm X
202conversions) prepended to it.
203For
204.Cm a ,
205.Cm A ,
206.Cm e ,
207.Cm E ,
208.Cm f ,
209.Cm F ,
210.Cm g ,
211and
212.Cm G
213conversions, the result will always contain a decimal point, even if no
214digits follow it (normally, a decimal point appears in the results of
215those conversions only if a digit follows).
216For
217.Cm g
218and
219.Cm G
220conversions, trailing zeros are not removed from the result as they
221would otherwise be.
222For all other formats, behaviour is undefined.
223.It
224A zero
225.Sq Cm \&0
226character specifying zero padding.
227For all conversions except
228.Cm n ,
229the converted value is padded on the left with zeros rather than blanks.
230If a precision is given with a numeric conversion
231.Pf ( Cm d ,
232.Cm i ,
233.Cm o ,
234.Cm u ,
235.Cm x ,
236and
237.Cm X ) ,
238the
239.Sq Cm \&0
240flag is ignored.
241.It
242A negative field width flag
243.Sq Cm \-
244indicates the converted value is to be left adjusted on the field boundary.
245Except for
246.Cm n
247conversions, the converted value is padded on the right with blanks,
248rather than on the left with blanks or zeros.
249A
250.Sq Cm \-
251overrides a
252.Sq Cm \&0
253if both are given.
254.It
255A space, specifying that a blank should be left before a positive number
256produced by a signed conversion
257.Pf ( Cm d ,
258.Cm a ,
259.Cm A ,
260.Cm e ,
261.Cm E ,
262.Cm f ,
263.Cm F ,
264.Cm g ,
265.Cm G ,
266or
267.Cm i ) .
268.It
269A
270.Sq Cm +
271character specifying that a sign always be placed before a
272number produced by a signed conversion.
273A
274.Sq Cm +
275overrides a space if both are used.
276.El
277.It
278An optional decimal digit string specifying a minimum field width.
279If the converted value has fewer characters than the field width, it will
280be padded with spaces on the left (or right, if the left-adjustment
281flag has been given) to fill out
282the field width.
283.It
284An optional precision, in the form of a period
285.Sq Cm \&.
286followed by an
287optional digit string.
288If the digit string is omitted, the precision is taken as zero.
289This gives the minimum number of digits to appear for
290.Cm d ,
291.Cm i ,
292.Cm o ,
293.Cm u ,
294.Cm x ,
295and
296.Cm X
297conversions, the number of digits to appear after the decimal-point for
298.Cm a ,
299.Cm A ,
300.Cm e ,
301.Cm E ,
302.Cm f ,
303and
304.Cm F
305conversions, the maximum number of significant digits for
306.Cm g
307and
308.Cm G
309conversions, or the maximum number of characters to be printed from a
310string for
311.Cm s
312conversions.
313.It
314An optional length modifier, that specifies the size of the argument.
315The following length modifiers are valid for the
316.Cm d , i , n ,
317.Cm o , u , x ,
318or
319.Cm X
320conversions:
321.Bl -column "(deprecated)" "signed char" "unsigned long long" "long long *"
322.It Sy Modifier Ta Sy "d, i" Ta Sy "o, u, x, X" Ta Sy n
323.It hh Ta "signed char" Ta "unsigned char" Ta "signed char *"
324.It h Ta short Ta "unsigned short" Ta "short *"
325.It "l (ell)" Ta long Ta "unsigned long" Ta "long *"
326.It "ll (ell ell)" Ta "long long" Ta "unsigned long long" Ta "long long *"
327.It j Ta intmax_t Ta uintmax_t Ta "intmax_t *"
328.It t Ta ptrdiff_t Ta (see note) Ta "ptrdiff_t *"
329.It z Ta "(see note)" Ta size_t Ta "(see note)"
330.It "q (deprecated)" Ta quad_t Ta u_quad_t Ta "quad_t *"
331.El
332.Pp
333Note:
334the
335.Cm t
336modifier, when applied to an
337.Cm o , u , x ,
338or
339.Cm X
340conversion, indicates that the argument is of an unsigned type
341equivalent in size to a
342.Vt ptrdiff_t .
343The
344.Cm z
345modifier, when applied to a
346.Cm d
347or
348.Cm i
349conversion, indicates that the argument is of a signed type equivalent in
350size to a
351.Vt size_t .
352Similarly, when applied to an
353.Cm n
354conversion, it indicates that the argument is a pointer to a signed type
355equivalent in size to a
356.Vt size_t .
357.Pp
358The following length modifiers are valid for the
359.Cm a ,
360.Cm A ,
361.Cm e ,
362.Cm E ,
363.Cm f ,
364.Cm F ,
365.Cm g ,
366or
367.Cm G
368conversions:
369.Bl -column "Modifier" "e, E, f, F, g, G"
370.It Sy Modifier Ta Sy "e, E, f, F, g, G"
371.It "l (ell)" Ta double (ignored: same behavior as without it)
372.It L Ta "long double"
373.El
374.Pp
375The following length modifier is valid for the
376.Cm c
377or
378.Cm s
379conversions:
380.Bl -column "Modifier" "wint_t" "wchar_t *"
381.It Sy Modifier Ta Sy c Ta Sy s
382.It "l (ell)" Ta wint_t Ta "wchar_t *"
383.El
384.It
385A character that specifies the type of conversion to be applied.
386.El
387.Pp
388A field width or precision, or both, may be indicated by
389an asterisk
390.Ql *
391or an asterisk followed by one or more decimal digits and a
392.Ql $
393instead of a
394digit string.
395In this case, an
396.Li int
397argument supplies the field width or precision.
398A negative field width is treated as a left adjustment flag followed by a
399positive field width; a negative precision is treated as though it were
400missing.
401If a single format directive mixes positional (nn$) and
402non-positional arguments, the results are undefined.
403.Pp
404The conversion specifiers and their meanings are:
405.Bl -tag -width "diouxX"
406.It Cm diouxX
407The
408.Li int
409(or appropriate variant) argument is converted to signed decimal
410.Pf ( Cm d
411and
412.Cm i ) ,
413unsigned octal
414.Pq Cm o ,
415unsigned decimal
416.Pq Cm u ,
417or unsigned hexadecimal
418.Pf ( Cm x
419and
420.Cm X )
421notation.
422The letters
423.Cm abcdef
424are used for
425.Cm x
426conversions; the letters
427.Cm ABCDEF
428are used for
429.Cm X
430conversions.
431The precision, if any, gives the minimum number of digits that must
432appear; if the converted value requires fewer digits, it is padded on
433the left with zeros.
434.It Cm DOU
435The
436.Li long int
437argument is converted to signed decimal, unsigned octal, or unsigned
438decimal, as if the format had been
439.Cm ld ,
440.Cm lo ,
441or
442.Cm lu
443respectively.
444These conversion characters are deprecated, and will eventually disappear.
445.It Cm eE
446The
447.Li double
448argument is rounded and converted in the style
449.Sm off
450.Pf [\-]d Cm \&. No ddd Cm e No \(+-dd
451.Sm on
452where there is one digit before the
453decimal-point character
454and the number of digits after it is equal to the precision;
455if the precision is missing,
456it is taken as 6; if the precision is
457zero, no decimal-point character appears.
458An
459.Cm E
460conversion uses the letter
461.Cm E
462(rather than
463.Cm e )
464to introduce the exponent.
465The exponent always contains at least two digits; if the value is zero,
466the exponent is 00.
467.Pp
468If the argument is infinity, it will be converted to [-]inf
469.Pq Cm e
470or [-]INF
471.Pq Cm E ,
472respectively.
473If the argument is not-a-number (NaN), it will be converted to
474[-]nan
475.Pq Cm e
476or [-]NAN
477.Pq Cm E ,
478respectively.
479.It Cm fF
480The
481.Li double
482argument is rounded and converted to decimal notation in the style
483.Sm off
484.Pf [-]ddd Cm \&. No ddd ,
485.Sm on
486where the number of digits after the decimal-point character
487is equal to the precision specification.
488If the precision is missing, it is taken as 6; if the precision is
489explicitly zero, no decimal-point character appears.
490If a decimal point appears, at least one digit appears before it.
491.Pp
492If the argument is infinity, it will be converted to [-]inf
493.Pq Cm f
494or [-]INF
495.Pq Cm F ,
496respectively.
497If the argument is not-a-number (NaN), it will be converted to
498[-]nan
499.Pq Cm f
500or [-]NAN
501.Pq Cm F ,
502respectively.
503.It Cm gG
504The
505.Li double
506argument is converted in style
507.Cm f
508or
509.Cm e
510(or
511.Cm E
512for
513.Cm G
514conversions).
515The precision specifies the number of significant digits.
516If the precision is missing, 6 digits are given; if the precision is zero,
517it is treated as 1.
518Style
519.Cm e
520is used if the exponent from its conversion is less than -4 or greater than
521or equal to the precision.
522Trailing zeros are removed from the fractional part of the result; a
523decimal point appears only if it is followed by at least one digit.
524.Pp
525If the argument is infinity, it will be converted to [-]inf
526.Pq Cm g
527or [-]INF
528.Pq Cm G ,
529respectively.
530If the argument is not-a-number (NaN), it will be converted to
531[-]nan
532.Pq Cm g
533or [-]NAN
534.Pq Cm G ,
535respectively.
536.It Cm aA
537The
538.Li double
539argument is rounded and converted to hexadecimal notation in the style
540.Sm off
541.Pf [\-]0xh Cm \&. No hhh Cm p No [\(+-]d
542.Sm on
543where the number of digits after the hexadecimal-point character
544is equal to the precision specification.
545If the precision is missing, it is taken as enough to represent
546the floating-point number exactly, and no rounding occurs.
547If the precision is zero, no hexadecimal-point character appears.
548The
549.Cm p
550is a literal character
551.Ql p ,
552and the exponent consists of a positive or negative sign
553followed by a decimal number representing an exponent of 2.
554The
555.Cm A
556conversion uses the prefix
557.Dq Li 0X
558(rather than
559.Dq Li 0x ) ,
560the letters
561.Dq Li ABCDEF
562(rather than
563.Dq Li abcdef )
564to represent the hex digits, and the letter
565.Ql P
566(rather than
567.Ql p )
568to separate the mantissa and exponent.
569.Pp
570Note that there may be multiple valid ways to represent floating-point
571numbers in this hexadecimal format.
572For example,
573.Li 0x3.24p+0 , 0x6.48p-1
574and
575.Li 0xc.9p-2
576are all equivalent.
577The format chosen depends on the internal representation of the
578number, but the implementation guarantees that the length of the
579mantissa will be minimized.
580Zeroes are always represented with a mantissa of 0 (preceded by a
581.Ql -
582if appropriate) and an exponent of
583.Li +0 .
584.Pp
585If the argument is infinity, it will be converted to [-]inf
586.Pq Cm a
587or [-]INF
588.Pq Cm A ,
589respectively.
590If the argument is not-a-number (NaN), it will be converted to
591[-]nan
592.Pq Cm a
593or [-]NAN
594.Pq Cm A ,
595respectively.
596.It Cm c
597The
598.Li int
599argument is converted to an
600.Li unsigned char ,
601and the resulting character is written.
602.It Cm s
603The
604.Li char *
605argument is expected to be a pointer to an array of character type (pointer
606to a string).
607Characters from the array are written up to (but not including)
608a terminating NUL character;
609if a precision is specified, no more than the number specified are
610written.
611If a precision is given, no NUL character need be present;
612if the precision is not specified, or is greater than the size
613of the array, the array must contain a terminating NUL character.
614.It Cm p
615The
616.Li void *
617pointer argument is printed in hexadecimal (as if by
618.Ql %#x
619or
620.Ql %#lx ) .
621.It Cm n
622The number of characters written so far is stored into the
623integer indicated by the
624.Li int *
625(or variant) pointer argument.
626No argument is converted.
627.It Cm %
628A
629.Ql %
630is written.
631No argument is converted.
632The complete conversion specification is
633.Ql %% .
634.El
635.Pp
636In no case does a non-existent or small field width cause truncation of
637a field; if the result of a conversion is wider than the field width, the
638field is expanded to contain the conversion result.
639.Sh RETURN VALUES
640For all these functions if an output or encoding error occurs, a value
641less than 0 is returned.
642.Pp
643The
644.Fn printf ,
645.Fn dprintf ,
646.Fn fprintf ,
647.Fn sprintf ,
648.Fn vprintf ,
649.Fn vdprintf ,
650.Fn vfprintf ,
651.Fn vsprintf ,
652.Fn asprintf ,
653and
654.Fn vasprintf
655functions
656return the number of characters printed
657(not including the trailing
658.Ql \e0
659used to end output to strings).
660.Pp
661The
662.Fn snprintf
663and
664.Fn vsnprintf
665functions return the number of characters that would have
666been output if the
667.Fa size
668were unlimited
669.Po
670again, not including the final
671.Ql \e0
672.Pc .
673A return value greater than or equal to the
674.Fa size
675argument indicates that the string was too small and some characters
676were discarded.
677.Pp
678The
679.Fn asprintf
680and
681.Fn vasprintf
682functions return the number of characters that were output
683to the newly allocated string
684(excluding the final
685.Ql \e0 ) .
686A pointer to the newly allocated string is returned in
687.Fa ret ;
688it should be passed to
689.Xr free 3
690to release the allocated storage
691when it is no longer needed.
692If sufficient space cannot be allocated or some other error occurs,
693these functions return \-1.
694The value of
695.Fa ret
696in this situation is implementation-dependent.
697On
698.Ox ,
699.Fa ret
700is set to the
701.Dv NULL
702pointer, but other implementations may leave
703.Fa ret
704unchanged.
705.Sh EXAMPLES
706To print a date and time in the form `Sunday, July 3, 10:02',
707where
708.Va weekday
709and
710.Va month
711are pointers to strings:
712.Bd -literal -offset indent
713#include <stdio.h>
714
715fprintf(stdout, "%s, %s %d, %.2d:%.2d\en",
716    weekday, month, day, hour, min);
717.Ed
718.Pp
719To print \*(Pi
720to five decimal places:
721.Bd -literal -offset indent
722#include <math.h>
723#include <stdio.h>
724
725fprintf(stdout, "pi = %.5f\en", 4 * atan(1.0));
726.Ed
727.Pp
728To allocate a 128-byte string and print into it:
729.Bd -literal -offset indent
730#include <stdarg.h>
731#include <stdio.h>
732#include <stdlib.h>
733
734char *
735newfmt(const char *fmt, ...)
736{
737	char *p;
738	va_list ap;
739
740	if ((p = malloc(128)) == NULL)
741		return (NULL);
742	va_start(ap, fmt);
743	(void) vsnprintf(p, 128, fmt, ap);
744	va_end(ap);
745	return (p);
746}
747.Ed
748.Sh ERRORS
749In addition to the errors documented for the
750.Xr write 2
751system call, the
752.Fn printf
753family of functions may fail if:
754.Bl -tag -width Er
755.It Bq Er EILSEQ
756An invalid wide character code was encountered.
757.It Bq Er ENOMEM
758Insufficient storage space is available.
759.It Bq Er EOVERFLOW
760The return value would be too large to be represented by an
761.Vt int .
762.El
763.Sh SEE ALSO
764.Xr printf 1 ,
765.Xr scanf 3 ,
766.Xr wprintf 3
767.Sh STANDARDS
768The
769.Fn fprintf ,
770.Fn printf ,
771.Fn snprintf ,
772.Fn sprintf ,
773.Fn vfprintf ,
774.Fn vprintf ,
775.Fn vsnprintf ,
776and
777.Fn vsprintf
778functions conform to
779.St -isoC-99 .
780The
781.Fn dprintf
782and
783.Fn vdprintf
784functions conform to
785.St -p1003.1-2008 .
786.Sh HISTORY
787The predecessors
788.Fn ftoa
789and
790.Fn itoa
791first appeared in
792.At v1 .
793The function
794.Fn printf
795first appeared in
796.At v2 ,
797and
798.Fn fprintf
799and
800.Fn sprintf
801in
802.At v7 .
803.Pp
804The functions
805.Fn snprintf
806and
807.Fn vsnprintf
808first appeared in
809.Bx 4.4 .
810.Pp
811The functions
812.Fn asprintf
813and
814.Fn vasprintf
815first appeared in the GNU C library.
816This implementation first appeared in
817.Ox 2.3 .
818.Pp
819The functions
820.Fn dprintf
821and
822.Fn vdprintf
823first appeared in
824.Ox 5.3 .
825.Sh CAVEATS
826The conversion formats
827.Cm \&%D ,
828.Cm \&%O ,
829and
830.Cm \&%U
831are not standard and
832are provided only for backward compatibility.
833The effect of padding the
834.Cm %p
835format with zeros (either by the
836.Sq Cm 0
837flag or by specifying a precision), and the benign effect (i.e., none)
838of the
839.Sq Cm #
840flag on
841.Cm %n
842and
843.Cm %p
844conversions, as well as other
845nonsensical combinations such as
846.Cm %Ld ,
847are not standard; such combinations
848should be avoided.
849.Pp
850Because
851.Fn sprintf
852and
853.Fn vsprintf
854assume an infinitely long string,
855callers must be careful not to overflow the actual space;
856this is often impossible to assure.
857For safety, programmers should use the
858.Fn snprintf
859and
860.Fn asprintf
861family of interfaces instead.
862Unfortunately, the
863.Fn asprintf
864interface is not available on all systems as it is not part of
865.St -isoC-99 .
866.Pp
867It is important never to pass a string with user-supplied data as a
868format without using
869.Ql %s .
870An attacker can put format specifiers in the string to mangle the stack,
871leading to a possible security hole.
872This holds true even if the string has been built
873.Dq by hand
874using a function like
875.Fn snprintf ,
876as the resulting string may still contain user-supplied conversion specifiers
877for later interpolation by
878.Fn printf .
879.Pp
880Be sure to use the proper secure idiom:
881.Bd -literal -offset indent
882int ret = snprintf(buffer, sizeof(buffer), "%s", string);
883if (ret < 0 || ret >= sizeof(buffer))
884	goto toolong;
885.Ed
886.Pp
887There is no way for
888.Fn printf
889to know the size of each argument passed.
890If positional arguments are used, care must be taken to ensure that all
891parameters, up to the
892last positionally specified parameter, are used in the format string.
893This allows for the format string to be parsed for this information.
894Failure to do this will mean the code is non-portable and liable to fail.
895.Pp
896On systems other than
897.Ox ,
898the
899.Dv LC_NUMERIC
900.Xr locale 1
901category can cause erratic output; see CAVEATS in
902.Xr setlocale 3
903for details.
904