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