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