printf() — Print Formatted Characters

Format

#include <stdio.h>
int printf(const char *format-string, argument-list);

Language Level

ANSI

Threadsafe

Yes

Locale Sensitive

The behavior of this function might be affected by the LC_CTYPE and LC_NUMERIC categories of the current locale. The behavior might also be affected by the LC_UNI_CTYPE category of the current locale if LOCALETYPE(*LOCALEUCS2) or LOCALETYPE(*LOCALEUTF) is specified on the compilation command. For more information, see Understanding CCSIDs and Locales.

Description

The printf() function formats and prints a series of characters and values to the standard output stream stdout. Format specifications, beginning with a percent sign (%), determine the output format for any argument-list following the format-string. The format-string is a multibyte character string beginning and ending in its initial shift state.

The format-string is read left to right. When the first format specification is found, the value of the first argument after the format-string is converted and printed according to the format specification. The second format specification causes the second argument after the format-string to be converted and printed, and so on through the end of the format-string. If there are more arguments than there are format specifications, the extra arguments are evaluated and ignored. The results are undefined if there are not enough arguments for all the format specifications.

A format specification has the following form:

Read syntax diagramSkip visual syntax diagram%flagswidth.precisionhLlllHDDDtype

Conversions can be applied to the nth argument after the format-string in the argument list, rather than to the next unused argument. In this case, the conversion character % is replaced by the sequence %n$, where n is a decimal integer in the range 1 through NL_ARGMAX, giving the position of the argument in the argument list. This feature provides for the definition of format strings that select arguments in an order appropriate to specific languages.

Alternative format specification has the following form:
Read syntax diagramSkip visual syntax diagram%arg-number$flags width.precisionhLlllHDDDtype

As an alternative, specific entries in the argument-list can be assigned by using the format specification outlined in the preceding diagram. This format specification and the previous format specification cannot be mixed in the same call to printf(). Otherwise, unpredictable results might occur.

The arg-number is a positive integer constant where 1 refers to the first entry in the argument-list. Arg-number cannot be greater than the number of entries in the argument-list, or else the results are undefined. Arg-number also may not be greater than NL_ARGMAX.

In format strings containing the %n$ form of conversion specifications, numbered arguments in the argument list can be referenced from the format string as many times as required.

In format strings containing the %n$ form of a conversion specification, a field width or precision may be indicated by the sequence *m$, where m is a decimal integer in the range 1 thru NL_ARGMAX giving the position in the argument list (after the format argument) of an integer argument containing the field width or precision, for example:

printf("%1$d:%2$.*3$d:%4$.*3$d\n", hour, min, precision, sec);

The format-string can contain either numbered argument specifications (that is, %n$ and *m$), or unnumbered argument specifications (that is, % and *), but normally not both. The only exception to this is that %% can be mixed with the %n$ form. The results of mixing numbered and unnumbered argument specifications in a format-string string are undefined. When numbered argument specifications are used, specifying the nth argument requires that all the leading arguments, from the first to the (n-1)th, are specified in the format string.

Each field of the format specification is a single character or number signifying a particular format option. The type character, which appears after the last optional format field, determines whether the associated argument is interpreted as a character, a string, a number, or pointer. The simplest format specification contains only the percent sign and a type character (for example, %s).

The following optional fields control other aspects of the formatting:
Field
Description
flags
Justification of output and printing of signs, blanks, decimal points, octal, and hexadecimal prefixes, and the semantics for wchar_t precision unit.
width
Minimum number of bytes output.
precision
See Table 2.
h, l, ll, L, H, D, DD
Size of argument expected:
h
A prefix with d, i, o, u, x, X, and n types that specifies that the argument is a short int or unsigned short int.
l
A prefix with d, i, o, u, x, X, and n types that specifies that the argument is a long int or unsigned long int.
ll
A prefix with d, i, o, u, x, X, and n types that specifies that the argument is a long long int or unsigned long long int.
L
A prefix with a, A, e, E, f, F, g, or G types that specifies that the argument is long double.
H
A prefix with a, A, e, E, f, F, g, or G types that specifies that the argument is _Decimal32.
D
A prefix with a, A, e, E, f, F, g, or G types that specifies that the argument is _Decimal64.
DD
A prefix with a, A, e, E, f, F, g, or G types that specifies that the argument is _Decimal128.

Each field of the format specification is discussed in detail below. If a percent sign (%) is followed by a character that has no meaning as a format field, the behavior is undefined. One exception to this behavior is %%. To print a percent-sign character, use %%.

The type characters and their meanings are given in the following table:

Table 1. Type characters
Character Argument Output Format
a Floating-point For non decimal floating-point numbers, signed value having the form [-]0xh.hhhhp[sign]ddd, where h is a single hexadecimal digit, hhhh is one or more hexadecimal digits, ddd is one or more decimal digits, and sign is + or -. The number of hexadecimal digits after the decimal point is equal to the requested precision.

For decimal floating-point numbers, if the precision is missing, either the f or e style formatting is used based on the following criteria.

  • f style formatting is used when the quantum exponent of the value is less than or equal to 0 but greater than or equal to -(n+5). The quantum exponent of a number can be determined by calling the quantexp64() function. n is the number of digits in the digit-sequence (including trailing zeros) when the decimal point is ignored. For example:

    0.000005

    contains 1 digit in the digit sequence, n = 1

    0.0000050

    contains 2 digits in the digit sequence, n = 2

    12.30

    contains 4 digits in the digit sequence, n = 4

    The precision is equal to the absolute value of the quantum exponent of the value.

  • e style formatting is used when the quantum exponent of the value does not satisfy the f style criteria. The precision is equal to n-1. The e style format of a decimal floating-point value is the same as the e style format of a non decimal floating-point value with two exceptions: a) if the value is equal to 0 then the exponent is equal to the quantum exponent of the value, and b) the exponent is always given with the minimum number of digits required (i.e., the exponent never contains a leading zero). For example:

    0.0000000 produces 0e-7

    -1870 produces -1.87e+3

If the precision modifier is present and at least as large as the precision of the value, the conversion is as if the precision modifier were missing. If the precision modifier is present and less than the precision of the value, the value is first rounded to the number of digits specified by the precision modifier. The result is then converted as if the precision modifier were missing.
A Floating-point Identical to the a format except that uppercase alphabetic characters are used instead of lowercase alphabetic characters.
d, i Integer Signed decimal integer.
u Integer Unsigned decimal integer.
o Integer Unsigned octal integer.
x Integer Unsigned hexadecimal integer, using abcdef.
X Integer Unsigned hexadecimal integer, using ABCDEF.
D(n,p) Packed decimal It has the format [-] dddd.dddd where the number of digits after the decimal point is equal to the precision of the specification. If the precision is missing, the default is p; if the precision is zero, and the # flag is not specified, no decimal point character appears. If the n and the p are *, an argument from the argument list supplies the value. n and p must precede the value being formatted in the argument list. At least one character appears before a decimal point. The value is rounded to the appropriate number of digits.
f Floating-point Signed value having the form [-]dddd.dddd, where dddd is one or more decimal digits. The number of digits before the decimal point depends on the magnitude of the number. The number of digits after the decimal point is equal to the requested precision.2
F Floating-point Identical to the f format except that uppercase alphabetic characters are used instead of lowercase alphabetic characters.2
e Floating-point Signed value having the form [-]d.dddd e[sign]ddd, where d is a single-decimal digit, dddd is one or more decimal digits, ddd is 2 or more decimal digits, and sign is + or -.2
E Floating-point Identical to the e format except that uppercase alphabetic characters are used instead of lowercase alphabetic characters.2
g Floating-point Signed value printed in f or e format. The e format is used only when the exponent of the value is less than -4 or greater than or equal to precision. Trailing zeros are truncated, and the decimal point appears only if one or more digits follow it.2
G Floating-point Identical to the g format except that uppercase alphabetic characters are used instead of lowercase alphabetic characters.2
c Character (byte) Single character.
s String Characters (bytes) printed up to the first null character (\0) or until precision is reached.
n Pointer to integer Number of characters (bytes) successfully written so far to the stream or buffer; this value is stored in the integer whose address is given as the argument.
p Pointer Pointer converted to a sequence of printable characters. It can be one of the following:
  • space pointer
  • system pointer
  • invocation pointer
  • procedure pointer
  • open pointer
  • suspend pointer
  • data pointer
  • label pointer
lc or C Wide Character The (wchar_t) character is converted to a multibyte character as if by a call to wctomb(), and this character is printed out.1
ls or S Wide Character The (wchar_t) characters up to the first (wchar_t) null character (L\0), or until precision is reached, are converted to multibyte characters, as if by a call to wcstombs(), and these characters are printed out. If the argument is a null string, (null) is printed.1
Note:
  1. See the documentation for the wctomb() function or the documentation for the wcstombs() function for more information. You can also find additional information in Wide Characters.
  2. If the H, D, or DD format size specifiers are not used, only 15 significant digits of output are guaranteed.

The following list shows the format of the printed values for IBM® i pointers, and gives a brief description of the components of the printed values.

Space pointer:  SPP:Context:Object:Offset:AG

        Context: type, subtype and name of the context
        Object:  type, subtype and name of the object
        Offset:  offset within the space
        AG:      Activation group ID

System pointer:  SYP:Context:Object:Auth:Index:AG

        Context: type, subtype and name of the context
        Object:  type, subtype and name of the object
        Auth:    authority
        Index:   Index associated with the pointer
        AG:      Activation group ID

Invocation pointer:  IVP:Index:AG

        Index:   Index associated with the pointer
        AG:      Activation group ID

Procedure pointer:  PRP:Index:AG

        Index:   Index associated with the pointer
        AG:      Activation group ID

Suspend pointer:  SUP:Index:AG

        Index:   Index associated with the pointer
        AG:      Activation group ID

Data pointer:  DTP:Index:AG

        Index:   Index associated with the pointer
        AG:      Activation group ID

Label pointer:  LBP:Index:AG

        Index:   Index associated with the pointer
        AG:      Activation group ID

NULL pointer:  NULL

The following restrictions apply to pointer printing and scanning on the IBM i operating system:
  • If a pointer is printed out and scanned back from the same activation group, the scanned back pointer will be compared equal to the pointer printed out.
  • If a scanf() family function scans a pointer that was printed out by a different activation group, the scanf() family function will set the pointer to NULL.
  • If a pointer is printed out in a teraspace environment, just the hexadecimal value of the pointer is printed out. These results are the same as when using %#p.

The %#p format specifier has much better performance than the %p format specifier.

See the ILE C/C++ Programmer's Guide for more information about using IBM i pointers.

If a floating-point value of INFINITY or Not-a-Number (NaN) is formatted using the a, e, f, or g format, the output string is infinity or nan. If a floating-point value of INFINITY or Not-A-Number (NaN) is formatted using the A, E, F, or G format, the output string is INFINITY or NAN.

The flag characters and their meanings are as follows (notice that more than one flag can appear in a format specification):

Flag Meaning Default
- Left-justify the result within the field width. Right-justify.
+ Prefix the output value with a sign (+ or -) if the output value is of a signed type. Sign appears only for negative signed values (-).
blank(' ') Prefix the output value with a blank if the output value is signed and positive. The + flag overrides the blank flag if both appear, and a positive signed value will be output with a sign. No blank.
# When used with the o, x, or X formats, the # flag prefixes any nonzero output value with 0, 0x, or 0X, respectively. No prefix.
When used with the D(n,p), a, A, e, E, f or F formats, the # flag forces the output value to contain a decimal point in all cases. Decimal point appears only if digits follow it.
When used with the g or G formats, the # flag forces the output value to contain a decimal point in all cases and prevents the truncation of trailing zeros. Decimal point appears only if digits follow it; trailing zeros are truncated.
When used with the ls or S format, the # flag causes precision to be measured in characters, regardless of the size of the character. For example, if single-byte characters are being printed, a precision of 4 would result in 4 bytes being printed. If double-byte characters are being printed, a precision of 4 would result in 8 bytes being printed. Precision indicates the maximum number of bytes to be output.
When used with the p format, the # flag converts the pointer to hex digits. These hex digits cannot be converted back into a pointer, unless in a teraspace environment. Pointer converted to a sequence of printable characters.
0 When used with the d, i, D(n,p) o, u, x, X, a, A, e, E, f, F, g, or G formats, the 0 flag causes leading 0s to pad the output to the field width. The 0 flag is ignored if precision is specified for an integer or if the - flag is specified. Space padding. No space padding for D(n,p).

The # flag should not be used with c, lc, d, i, u, or s types.

Width is a nonnegative decimal integer controlling the minimum number of characters printed. If the number of characters (bytes) in the output value is less than the specified width, blanks are added on the left or the right (depending on whether the - flag is specified) until the minimum width is reached.

Width never causes a value to be truncated; if the number of characters (bytes) in the output value is greater than the specified width, or width is not given, all characters of the value are printed (subject to the precision specification).

For the ls or S type, width is specified in bytes. If the number of bytes in the output value is less than the specified width, single-byte blanks are added on the left or the right (depending on whether the - flag is specified) until the minimum width is reached.

The width specification can be an asterisk (*), in which case an argument from the argument list supplies the value. The width argument must precede the value being formatted in the argument list.

Precision is a nonnegative decimal integer preceded by a period, which specifies the number of characters to be printed or the number of decimal places. Unlike the width specification, the precision can cause truncation of the output value or rounding of a floating-point or packed decimal value.

The precision specification can be an asterisk (*), in which case an argument from the argument list supplies the value. The precision argument must precede the value being formatted in the argument list.

The interpretation of the precision value and the default when the precision is omitted depend on the type, as shown in the following table:

Table 2. Values of Precision
Type Meaning Default
  a
  A
For non decimal floating-point numbers, precision specifies the number of hexadecimal digits to be printed after the decimal point.

For decimal floating-point numbers, precision specifies the number of significant digits to be printed.

For non decimal floating-point numbers, the default precision is sufficient for an exact representation of the value. If precision is 0, no decimal point is printed. For decimal floating-point numbers, the default precision is sufficient for an exact representation of the value. Refer to Table 1 for more details on the format used.
   i
   d
   u
   o
   x
   X
Precision specifies the minimum number of digits to be printed. If the number of digits in the argument is less than precision, the output value is padded on the left with zeros. The value is not truncated when the number of digits exceeds precision. If precision is 0 or omitted entirely, or if the period (.) appears without a number following it, the precision is set to 1.
   f
   F
   D(n,p)
   e
   E
Precision specifies the number of digits to be printed after the decimal point. The last digit printed is rounded. Default precision for f, F, e and E is six. Default precision for D(n,p) is p. If precision is 0 or the period appears without a number following it, no decimal point is printed.
   g
   G
Precision specifies the maximum number of significant digits printed. All significant digits are printed. Default precision is six.
   c
No effect. The character is printed.
   lc
No effect. The wchar_t character is converted and resulting multibyte character is printed.
   s
Precision specifies the maximum number of characters (bytes) to be printed. Characters (bytes) in excess of precision are not printed. Characters are printed until a null character is encountered.
   ls
Precision specifies the maximum number of bytes to be printed. Bytes in excess of precision are not printed; however, multibyte integrity is always preserved. wchar_t characters are converted and resulting multibyte characters are printed.

Return Value

The printf() function returns the number of bytes printed. The value of errno may be set to:
Value
Meaning
EBADMODE
The file mode that is specified is not valid.
ECONVERT
A conversion error occurred.
EIOERROR
A non-recoverable I/O error occurred.
EIORECERR
A recoverable I/O error occurred.
EILSEQ
An invalid multibyte character sequence was encountered.
EPUTANDGET
An illegal write operation occurred after a read operation.
ESTDOUT
stdout cannot be opened.
Note: The radix character for the printf() function is locale sensitive. The radix character is the decimal point to be used for the # flag character of the format string parameter for the format types D(n,p), a, A, e, E, f, F, g, and G.

Examples

This example prints data in a variety of formats.
#include <stdio.h>                                               
#include <stdlib.h>                                              
                                                                 
int main(void)                                                   
{                                                                
    char ch = 'h', *string = "computer";                         
    int count = 234, hex = 0x10, oct = 010, dec = 10;            
    double fp = 251.7366;                                        
    wchar_t wc = (wchar_t)0x0058;                                
    wchar_t ws[4];                                                       
                                                     
    printf("1234567890123%n4567890123456789\n\n", &count);          
    printf("Value of count should be 13; count = %d\n\n", count);   
    printf("%10c%5c\n", ch, ch);                                    
    printf("%25s\n%25.4s\n\n", string, string);                     
    printf("%f    %.2f    %e    %E\n\n", fp, fp, fp, fp);           
    printf("%i    %i     %i\n\n", hex, oct, dec);                   
}                                                                   
/*****************  Output should be similar to:  ***************** 
                                                                    
234   +234    000234     EA    ea     352                           
                                                                    
12345678901234567890123456789                                       
                                                                    
Value of count should be 13; count = 13                             
 
                                                                      
  h    h                                                              
          computer                                                    
              comp                                                    
                                                                      
251.736600    251.74    2.517366e+02    2.517366E+02                  
                                                                      
16    8     10                                                        
 
*******************************************************************/  

Example that uses printf()

     #include <stdio.h>
     #include <stdlib.h>
     #include <locale.h>
     /* This program is compiled with LOCALETYPE(*LOCALEUCS2) and             */
     /* SYSIFCOPT(*IFSIO)                                               */
     /* We will assume the locale setting is the same as the CCSID of the */
     /* job.  We will also assume any files involved have a CCSID of      */
     /* 65535 (no convert).  This way if printf goes to the screen or     */
     /* a file the output will be the same.                               */
    int main(void)
    {
        wchar_t wc = 0x0058;     /* UNICODE X */
        wchar_t ws[4];
        setlocale(LC_ALL,
         "/QSYS.LIB/EN_US.LOCALE"); /* a CCSID 37 locale */
        ws[0] = 0x0041;        /* UNICODE A   */
        ws[1] = (wchar_t)0x0042;        /* UNICODE B   */
        ws[2] = (wchar_t)0x0043;        /* UNICODE C   */
        ws[3] = (wchar_t)0x0000;
        /* The output displayed is CCSID 37  */
        printf("%lc   %ls\n\n",wc,ws);
        printf("%lc   %.2ls\n\n",wc,ws);

        /* Now let's try a mixed-byte CCSID example  */
        /* You would need a device that can handle mixed bytes to  */
        /* display this correctly.                         */

        setlocale(LC_ALL,
        "/QSYS.LIB/JA_JP.LOCALE");/* a CCSID 5026 locale */

        /* big A means an A that takes up 2 bytes on the screen   */
        /* It will look bigger then single byte A                 */
        ws[0] = (wchar_t)0xFF21;        /* UNICODE big A   */
        ws[1] = (wchar_t)0xFF22;        /* UNICODE big B   */
        ws[2] = (wchar_t)0xFF23;        /* UNICODE big C   */
        ws[3] = (wchar_t)0x0000;
        wc = 0xff11;                    /* UNICODE big 1   */

        printf("%lc   %ls\n\n",wc,ws);

        /* The output of this printf is not shown below and it   */
        /* will differ depending on the device you display it on,*/
        /* but if you looked at the string in hex it would look  */
        /* like this:  0E42F10F404040400E42C142C242C30F          */
        /* 0E is shift out, 0F is shift in, and 42F1 is the      */
        /* big 1 in CCSID   5026  */

        printf("%lc   %.4ls\n\n",wc,ws);

        /* The output of this printf is not shown below either. */
        /* The hex would look like:                             */
        /* 0E42F10F404040400E42C10F                             */
        /* Since the precision is in bytes we only get 4 bytes  */
        /* of the string.         */

        printf("%lc   %#.2ls\n\n",wc,ws);

        /* The output of this printf is not shown below either. */
        /* The hex would look like:                             */
        /* 0E42F10F404040400E42C142C20F                         */
        /* The # means precision is in characters reguardless   */
        /* of size.  So we get 2 characters of the string.      */
    }
 /*****************  Output should be similar to:  *****************


 X     ABC

 X     AB

 *******************************************************************/
 

Example that uses printf()

 #include <stdio.h>
 #include <stdlib.h>
 #include <locale.h>
 /* This program is compile LOCALETYPE(*LOCALE)  and               */
 /* SYSIFCOPT(*IFSIO)    */
 int main(void)
 {
     wchar_t wc = (wchar_t)0x00C4;     /*  D */
     wchar_t ws[4];
     ws[0] = (wchar_t)0x00C1;        /* A   */
     ws[1] = (wchar_t)0x00C2;        /* B   */
     ws[2] = (wchar_t)0x00C3;        /* C   */
     ws[3] = (wchar_t)0x0000;
     /* The output displayed is CCSID 37  */
     printf("%lc   %ls\n\n",wc,ws);

     /* Now let's try a mixed-byte CCSID example  */
     /* You would need a device that can handle mixed bytes to  */
     /* display this correctly.                         */

     setlocale(LC_ALL,
     "/QSYS.LIB/JA_JP.LOCALE"); /* a CCSID 5026 locale */

     /* big A means an A that takes up 2 bytes on the screen   */
     /* It will look bigger than single byte A                 */

     ws[0] = (wchar_t)0x42C1;        /* big A   */
     ws[1] = (wchar_t)0x42C2;        /* big B   */
     ws[2] = (wchar_t)0x42C3;        /* big C   */
     ws[3] = (wchar_t)0x0000;
     wc = 0x42F1;                    /* big 1   */

     printf("%lc   %ls\n\n",wc,ws);

     /* The output of this printf is not shown below and it   */
     /* will differ depending on the device you display it on,*/
     /* but if you looked at the string in hex it would look  */
     /* like this:  0E42F10F404040400E42C142C242C30F          */
     /* 0E is shift out, 0F is shift in, and 42F1 is the      */
     /* big 1 in CCSID   5026  */

     printf("%lc   %.4ls\n\n",wc,ws);

     /* The output of this printf is not shown below either. */
     /* The hex would look like:                             */
     /* 0E42F10F404040400E42C10F                             */
     /* Since the precision is in bytes we only get 4 bytes  */
     /* of the string.         */

     printf("%lc   %#.2ls\n\n",wc,ws);

     /* The output of this printf is not shown below either. */
     /* The hex would look like:                             */
     /* 0E42F10F404040400E42C142C20F                         */
     /* The # means precision is in characters regardless   */
     /* of size.  So we get 2 characters of the string.      */
 }
 /*****************  Output should be similar to:  *****************


 D     ABC


 *******************************************************************/
 

Related Information