is a C standard library function and is also a Linux terminal (shell) command that formats text and writes it to standard output. The function accepts a format C-string argument and a variable number of value arguments that the function serializes per the format string. Mismatch between the format specifiers and count and type of values results in undefined behavior, and the program might crash or vulnerabilities may arise.

The format string is encoded as a template language consisting of verbatim text and format specifiers that each specify how to serialize a value. As the format string is processed left-to-right, a subsequent value is used for each format specifier found. A format specifier starts with a character and has one or more following characters that specify how to serialize a value.

The standard library provides other, similar functions that form a family of printf-like functions. The functions share the same formatting capabilities but provide different behavior such as output to a different destination or safety measures that limit exposure to vulnerabilities. Functions of the printf-family have been implemented in other computer programming contexts (i.e., programming languages) with the same or similar syntax and semantics.

The C standard library function complements printf by providing formatted input (a.k.a. lexing, a.k.a. parsing) via a similar format string syntax.

The name, , is short for print formatted where print refers to output to a printer although the function is not limited to printer output. Today, print refers to output to any text-based environment such as a terminal or a file.

History 1950s: Fortran Early programming languages like Fortran used special statements with different syntax from other calculations to build formatting descriptions. (2+51+1 pages) In this example, the format is specified on line , and the command refers to it by line number: PRINT 601, IA, IB, AREA 601 FORMAT (4H A= ,I5,5H B= ,I5,8H AREA= ,F10.2, 13H SQUARE UNITS)

Hereby: indicates a string of 4 characters " A= " ( means Hollerith Field); indicates an integer field of width 5; indicates a floating-point field of width 10 with 2 digits after the decimal point.

An output with input arguments , , and might look like this: A= 100 B= 200 AREA= 1500.25 SQUARE UNITS

1960s: BCPL and ALGOL 68

In 1967, BCPL appeared. Its library included the routine which looked like any other function call. An example application looks like this: WRITEF("%I2-QUEENS PROBLEM HAS %I5 SOLUTIONS*N", NUMQUEENS, COUNT)

Hereby: indicates an integer of width 2 (the order of the format specification's field width and type is reversed compared to C's ); indicates an integer of width 5; is a BCPL language escape sequence representing a newline character (for which C uses the escape sequence ).

ALGOL 68 also had a function api, but used special syntax for the format: printf(($"Color "g", number1 "6d,", number2 "4zd,", hex "16r2d,", float "-d.2d,", unsigned value"-3d"."l$, "red", 123456, 89, BIN 255, 3.14, 250));

Using normal function syntax for the printing simplifies the language, and allows the printing to be implemented in the language itself. In most newer languages of that era I/O is not part of the syntax. However the format was usually not checked to see if it matched the type (or even the number) of values being printed.

1970s: C In 1973, was included as a C standard library routine as part of Version 4 Unix.

1990s: Shell command In 1990, the printf shell command, modeled after the C standard library function, was included with 4.3BSD-Reno. In 1991, a command was included with GNU shellutils (now part of GNU Core Utilities) and the syntax (options, arguments, etc.) of this "shell command" are different from the C-Language function e.g.: the "format section" does not use the positional arguments with a "$" symbol (n$) in the same way as printf() function:str="AA BB CC" # simple string with 3 fields set -- $str # convert fields to positional parameters printf "%s " $2 $3 $1; echo # in C printf() uses 2$ 3$.. # prints: BB CC AA

2000s: Java In 2004, Java 5.0 (1.5) released, which extended the class java.io.PrintStream, adding a method named printf() which functions analogously to printf() in C. Thus to print a formatted string to the standard output stream, one uses System.out.printf(). Java further introduced the method format to its string class java.lang.String.

2000s: -Wformat safety The need to do something about the range of problems resulting from lack of type safety has prompted attempts to make compilers -aware.

The option of GNU Compiler Collection (GCC) allows compile time checks to calls, enabling the compiler to detect a subset of invalid calls (and issue either a warning or an error, terminating compilation, as set by other flags).

Because the compiler inspects format specifiers, this feature effectively extends static analysis in C to include formatting aspects.

2020s: std::print

C++ added input/output support using the operator to avoid safety issues of printf. This used the type of the arguments to choose which code to execute to print them, avoiding the crashes that are possible with format strings. However, the syntax can be verbose (especially for setting options like precision), and remains available in C++ and is often used instead.

C++20 added a new API which uses a string consisting of verbatim text and placeholders followed by the values to print. The format string uses curly braces instead of percent signs, based on the syntax used in the Python standard library:

The recommended implementation is from Victor Zverovich's fmtlib which at compile time converts the string and argument types into an optimized formatting object, this is type-safe and syntax errors are detected at compile time. C++23 introduced the functions and which combined formatting and outputting, and is therefore a functional replacement for . It is possible to make a translator from a printf %-string to the same formatting object and this could produce a type-safe , but this was also not added to the spec. No analogous modernization has been introduced, though one has been proposed based on scnlib.

These functions (plus ) can print floating point accurately using the least number of trailing digits possible, an ability long missing from . Another useful feature is that they ignore the locale.

Format specifier Formatting of a value is specified as markup in the format string. For example, the following outputs Your age is and then the value of the variable in decimal format.

printf("Your age is %d", age);

Syntax The syntax for a format specifier is: %[parameter][flags][width][.precision][length]type

Parameter field The parameter field is optional. If included, then matching specifiers to values is sequential. The numeric value selects the n-th value parameter. This is a POSIX extension, not C99.

Text Description n is the index of the value parameter to serialize using this format specifier

This field allows for using the same value multiple times in a format string instead of having to pass the value multiple times. If a specifier includes this field, then subsequent specifiers must also.

For example, printf("%2$d %2$#x; %1$d %1$#x",16,17); outputs:

This field is very useful for localizing messages to different natural languages that use different word orders.

In the Windows API, support for this feature is via a different function, .

Flags field The flags field can be zero or more of (in any order):

Text Description Left-align the output of this placeholder; default is to right-align the output Prepends a plus sign for a positive value; by default a positive value does not have a prefix (space)Prepends a space character for a positive value; ignored if the flag exists; by default a positive value does not have a prefix When the 'width' option is specified, prepends zeros instead of spaces for numeric types; for example, produces " 3", while produces The integer or exponent of a decimal has the thousands grouping separator applied Alternate form: For and types, trailing zeros are not removed For , , , , , types, the output always contains a decimal point For , , types, the text , , , respectively, is prepended to non-zero numbers

Width field The width field specifies the number of characters to output. If the value can be represented in fewer characters, then the value is left-padded with spaces so that output is the number of characters specified. If the value requires more characters, then the output is longer than the specified width. A value is never truncated.

For example, specifies a width of 3 and outputs with a space on the left to output 3 characters. The call outputs which is 4 characters long since that is the minimum width for that value even though the width specified is 3.

If the width field is omitted, the output is the minimum number of characters for the value.

If the field is specified as , then the width value is read from the list of values in the call. For example, outputs 10 (<space>10) where the second parameter, , is the width (matches with ) and is the value to serialize (matches with ).

Though not part of the width field, a leading zero is interpreted as the zero-padding flag mentioned above, and a negative value is treated as the positive value in conjunction with the left-alignment flag also mentioned above.

The width field can be used to format values as a table (tabulated output). But, columns do not align if any value is larger than fits in the width specified. For example, notice that the last line value () does not fit in the first column of width 3 and therefore the column is not aligned.

1 1 12 12 123 123 1234 123

Precision field The precision field usually specifies a limit of the output, as set by the formatting type. For floating-point numeric types, it specifies the number of digits to the right of the decimal point to which the output should be rounded; for and it specifies the total number of significant figures (before and after the decimal, not including leading or trailing zeroes) to round to. For the string type, it limits the number of characters that should be output, after which the string is truncated.

The precision field may be omitted, or a numeric integer value, or a dynamic value when passed as another argument when indicated by an asterisk (). For example, outputs .

Length field The length field can be omitted or be any of:

Text Description For integer types, causes to expect an -sized integer argument which was promoted from a . For integer types, causes to expect an -sized integer argument which was promoted from a . For integer types, causes to expect a -sized integer argument. For floating-point types, this is ignored. arguments are always promoted to when used in a varargs call. For integer types, causes to expect a -sized integer argument. For floating-point types, causes to expect a argument. For integer types, causes to expect a -sized integer argument. For integer types, causes to expect a -sized integer argument. For integer types, causes to expect a -sized integer argument.

Platform-specific length options came to exist prior to widespread use of the ISO C99 extensions, including:

Text Description Commonly found platforms For signed integer types, causes to expect -sized integer argument; for unsigned integer types, causes to expect -sized integer argument Win32/Win64 For integer types, causes to expect a 32-bit (double word) integer argument Win32/Win64 For integer types, causes to expect a 64-bit (quad word) integer argument Win32/Win64 For integer types, causes to expect a 64-bit (quad word) integer argument BSD