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