Movatterモバイル変換


[0]ホーム

URL:


Jump to content
WikipediaThe Free Encyclopedia
Search

printf

From Wikipedia, the free encyclopedia
(Redirected fromPrintf format string)
C function to format and output text
icon
This articleneeds additional citations forverification. Please helpimprove this article byadding citations to reliable sources. Unsourced material may be challenged and removed.
Find sources: "Printf" – news ·newspapers ·books ·scholar ·JSTOR
(February 2015) (Learn how and when to remove this message)

Diagram illustrating syntax of printf function. The first argument to the function is a template string, which may contain format specifiers, which are introduced with the percent sign (%) character. Format specifiers instruct printf how to interpret and output values given in the corresponding arguments which follow the format string. printf replaces the format specifiers with the accordingly-interpreted contents of the remaining arguments, and outputs the result.
An example call to the printf function

printf is aC standard libraryfunction thatformatstext and writes it tostandard output. The function accepts a formatc-stringargument and avariable number of value arguments that the functionserializes per the format string. Mismatch between the format specifiers and count andtype of values results inundefined behavior and possibly programcrash or othervulnerability.

The format string isencoded as atemplate language consisting of verbatim text andformat 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 ofprintf-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 othercomputer programming contexts (i.e.,programming languages) with the same or similarsyntax andsemantics.

Thescanf() 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,printf, is short forprint formatted whereprint refers to output to aprinter although the function is not limited to printer output. Today, print refers to output to any text-based environment such as aterminal or afile.

History

[edit]

1950s: Fortran

[edit]

Early programming languages likeFortran used special statements with different syntax from other calculations to build formatting descriptions.[1] In this example, the format is specified on line601, and thePRINT[a] command refers to it by line number:

PRINT601,IA,IB,AREA 601FORMAT(4HA=,I5,5HB=,I5,8HAREA=,F10.2,13HSQUAREUNITS)

Hereby:

An output with input arguments100,200, and1500.25 might look like this:

 A=   100  B=   200  AREA=    1500.25 SQUARE UNITS

1960s: BCPL and ALGOL 68

[edit]

In 1967,BCPL appeared.[2] Its library included thewritef routine.[3] An example application looks like this:

WRITEF("%I2-QUEENS PROBLEM HAS %I5 SOLUTIONS*N", NUMQUEENS, COUNT)

Hereby:

  • %I2 indicates aninteger of width 2 (the order of the format specification's field width and type is reversed compared to C'sprintf);
  • %I5 indicates an integer of width 5;
  • *N is a BCPLlanguageescape sequence representing anewline character (for which C uses the escape sequence\n).

In 1968,ALGOL 68 had a more function-likeAPI, but still used special syntax (the$ delimiters surround special formatting syntax):

printf(($"Color "g", number1 "6d,", number2 "4zd,", hex "16r2d,", float "-d.2d,", unsigned value"-3d"."l$,"red",123456,89,BIN255,3.14,250));

In contrast to Fortran, using normal function calls and data types simplifies the language andcompiler, and allows the implementation of theinput/output (I/O) to be written in the same language.

These advantages were thought to outweigh the disadvantages (such as notype safety in many instances) up until the 2000s, and in most newer languages of that era I/O is not part of the syntax.

People have since learned[4] that this potentially results in consequences, ranging from security exploits to hardware failures (e.g., phone's networking capabilities being permanently disabled after trying to connect to an access point named "%p%s%s%s%s%n"[5]). Modern languages, such asC++20 and later, tend to include format specifications as a part of the language syntax,[6] which restore type safety in formatting to an extent, and allow the compiler to detect some invalid combinations of format specifiers and data types at compile time.

1970s: C

[edit]

In 1973,printf was included as a C standard library routine as part ofVersion 4 Unix.[7]

1990s: Shell command

[edit]

In 1990, theprintfshellcommand, modeled after the C standard library function, was included with4.3BSD-Reno.[8] In 1991, aprintf command was included with GNU shellutils (now part ofGNU Core Utilities).

2000s: Java

[edit]

In 2004,Java 5.0 (1.5) released, which extended the classjava.io.PrintStream, adding a method namedprintf() which functions analogously toprintf() in C. Thus to print a formatted string to the standard output stream, one usesSystem.out.printf(). Java further introduced the methodformat to its string classjava.lang.String.[9]

2000s: -Wformat safety

[edit]

The need to do something about the range of problems resulting from lack of type safety has prompted attempts to make the C++ compilerprintf-aware.

The-Wformat option ofGNU Compiler Collection (GCC) allowscompile time checks toprintf calls, enabling the compiler to detect a subset of invalid calls (and issue either a warning or an error, terminating compiling, as set by other flags).[10]

Since the compiler is inspectingprintf format specifiers, enabling this effectively extends the C++ syntax by making formatting a part of it.

2020s: std::print

[edit]

To address usability issues with the existingC++input/output support, and to avoid safety issues of printf[11] theC++ standard library was revised[12] to support a new type-safe formatting starting withC++20.[13] The approach ofstd::format() resulted from incorporating Victor Zverovich'slibfmt[14] API into the language specification[15] (Zverovich wrote[16] the first draft of the new format proposal); consequently,libfmt is an implementation of the C++20 format specification. InC++23, another function,std::print() andstd::println(), was introduced that combines formatting and outputting and therefore is a functional replacement forprintf().[17] However, no analogous::scanf() modernization has been introduced, though one has been proposed based onscnlib.[18]

As the format specification has become a part of the language syntax, a C++ compiler is able to prevent invalid combinations of types and format specifiers in many cases. Unlike the-Wformat option, this is not an optional feature.

The format specification oflibfmt andstd::format() is, in itself, an extensible "mini-language" (referred to as such in the specification),[19] an example of adomain-specific language. As such,std::print, completes a historical cycle; bringing the state-of-the-art (as of 2024) back to what it was in the case of Fortran's firstPRINT implementation in the 1950s.

Format specifier

[edit]

Formatting of a value is specified as markup in the format string. For example, the following outputsYour age is and then the value of the variableage in decimal format.

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

Syntax

[edit]

The syntax for a format specifier is:

%[parameter][flags][width][.precision][length]type

Parameter field

[edit]

The parameter field is optional. If included, then matching specifiers to values isnot sequential. The numeric valuen selects the n-th value parameter. This is aPOSIX extension; notC99.[citation needed]

TextDescription
n$n is the index of the value parameter toserialize 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:17 0x11; 16 0x10

This field is very useful forlocalizing messages to differentnatural languages that use differentword orders.

InWindows API, support for this feature is via a different function,printf_p.

Flags field

[edit]

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

TextDescription
-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
0When the 'width' option is specified, prepends zeros instead of spaces for numeric types; for example,printf("%4X",3) produces" 3", whileprintf("%04X",3); produces"0003"
'The integer or exponent of a decimal has the thousands grouping separator applied
#Alternate form:
Forg andG types, trailing zeros are not removed
Forf,F,e,E,g,G types, the output always contains a decimal point
Foro,x,X types, the text0,0x,0X, respectively, is prepended to non-zero numbers

Width field

[edit]

The width field specifies theminimum 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,printf("%3d",12); specifies a width of 3 and outputs12 with a space on the left to output 3 characters. The callprintf("%3d",1234); outputs1234 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.[20] For example,printf("%*d",3,10); outputs 10 (<space>10) where the second parameter,3, is the width (matches with*) and10 is the value toserialize (matches withd).

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 (1234) does not fit in the first column of width 3 and therefore the column is not aligned.

  1   1 12  12123 1231234 123

Precision field

[edit]

The precision field usually specifies amaximum limit of the output, as set by the formatting type. Forfloating-point numeric types, it specifies the number of digits to the right of the decimal point to which the output should be rounded; for%g and%G it specifies the total number ofsignificant figures (before and after the decimal, not including leading or trailing zeroes) to round to. For thestring 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,printf("%.*s",3,"abcdef"); outputsabc.

Length field

[edit]

The length field can be omitted or be any of:

TextDescription
hhFor integer types, causesprintf to expect anint-sized integer argument which was promoted from achar.
hFor integer types, causesprintf to expect anint-sized integer argument which was promoted from ashort.
lFor integer types, causesprintf to expect along-sized integer argument.

For floating-point types, this is ignored.float arguments are always promoted todouble when used in avarargs call.[21]

llFor integer types, causesprintf to expect along long-sized integer argument.
LFor floating-point types, causesprintf to expect along double argument.
zFor integer types, causesprintf to expect asize_t-sized integer argument.
jFor integer types, causesprintf to expect aintmax_t-sized integer argument.
tFor integer types, causesprintf to expect aptrdiff_t-sized integer argument.

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

TextDescriptionCommonly found platforms
IFor signed integer types, causesprintf to expectptrdiff_t-sized integer argument; for unsigned integer types, causesprintf to expectsize_t-sized integer argumentWin32/Win64
I32For integer types, causesprintf to expect a32-bit (double word) integer argumentWin32/Win64
I64For integer types, causesprintf to expect a64-bit (quad word) integer argumentWin32/Win64
qFor integer types, causesprintf to expect a 64-bit (quad word) integer argumentBSD

ISO C99 includes theinttypes.h header file that includes a number ofmacros forcross-platformprintf coding. For example:printf("%"PRId64,t); specifies decimal format for a64-bit signedinteger. Since the macros evaluate to astring literal, and the compilerconcatenates adjacent string literals, the expression"%"PRId64 compiles to a single string.

Macros include:

MacroDescription
PRId32Typically equivalent toI32d (Win32/Win64) ord
PRId64Typically equivalent toI64d (Win32/Win64),lld (32-bit platforms) orld (64-bit platforms)
PRIi32Typically equivalent toI32i (Win32/Win64) ori
PRIi64Typically equivalent toI64i (Win32/Win64),lli (32-bit platforms) orli (64-bit platforms)
PRIu32Typically equivalent toI32u (Win32/Win64) oru
PRIu64Typically equivalent toI64u (Win32/Win64),llu (32-bit platforms) orlu (64-bit platforms)
PRIx32Typically equivalent toI32x (Win32/Win64) orx
PRIx64Typically equivalent toI64x (Win32/Win64),llx (32-bit platforms) orlx (64-bit platforms)

Type field

[edit]

The type field can be any of:

TextDescription
%Output a literal% character; does not accept flags, width, precision or length fields
d,i(signed)int formatted as decimal;%d and%i are synonymous except when used withscanf
uunsigned int formatted as decimal.
f,Fdouble formatted asfixed-point;f andF only differs in how the strings for an infinite number orNaN are printed (inf,infinity andnan forf;INF,INFINITY andNAN forF)
e,Edouble formatted as in exponential notationd.ddddd;E results inE rather thane to introduce the exponent; the exponent always contains at least two digits; if the value is zero, the exponent is00; in Windows, the exponent contains three digits by default, e.g.1.5e002, but this can be altered by Microsoft-specific_set_output_format function
g,Gdouble formatted as either fixed-point or exponential notation, whichever is more appropriate for its magnitude;g uses lower-case letters,G uses upper-case letters; this type differs slightly from fixed-point notation in that insignificant zeroes to the right of the decimal point are not included, and that the precision field specifies the total number of significant digits rather than the digits after the decimal; the decimal point is not included on whole numbers
x,Xunsigned int formatted ashexadecimal;x uses lower-case letters andX uses upper-case
ounsigned int formatted asoctal
snull-terminated string
cchar
pPointer formatted in an implementation-defined way
a,Adouble in hexadecimal notation, starting with0x or0X.a uses lower-case letters,A uses upper-case letters[22][23]
nOutputs nothing but writes the number of characters written so far into an integerpointer parameter; inJava this prints anewline[24]

Custom data type formatting

[edit]

A common way to handle formatting with a custom data type is to format the custom data type value into astring, then use the%s specifier to include the serialized value in a larger message.

Some printf-like functions allow extensions to theescape-character-basedmini-language, thus allowing the programmer to use a specific formatting function for non-builtin types. One is the (nowdeprecated)glibc'sregister_printf_function(). However, it is rarely used due to the fact that it conflicts withstatic format string checking. Another isVstr custom formatters, which allows adding multi-character format names.

Some applications (like theApache HTTP Server) include their own printf-like function, and embed extensions into it. However these all tend to have the same problems thatregister_printf_function() has.

TheLinux kernelprintk function supports a number of ways to display kernel structures using the generic%p specification, byappending additional format characters.[25] For example,%pI4 prints anIPv4 address in dotted-decimal form. This allows static format string checking (of the%p portion) at the expense of full compatibility with normal printf.

Vulnerabilities

[edit]

Format string attack

[edit]

Extra value arguments are ignored, but if the format string has more format specifiers than value arguments passed, the behavior is undefined. For some C compilers, an extra format specifier results in consuming a value even though there isn't one which allows theformat string attack. Generally, for C, arguments arepassed on the stack. If too few arguments are passed, then printf can read past the end of the stack frame, thus allowing an attacker to read the stack.

Some compilers, likethe GNU Compiler Collection, willstatically check the format strings of printf-like functions and warn about problems (when using the flags-Wall or-Wformat). GCC will also warn about user-defined printf-style functions if the non-standard "format"__attribute__ is applied to the function.

Uncontrolled format string exploit

[edit]

The format string is often astring literal, which allowsstatic analysis of the function call. However, the format string can be the value of avariable, which allows for dynamic formatting but also a security vulnerability known as anuncontrolled format string exploit.

Memory write

[edit]

Although an output function on the surface,printf allows writing to a memory location specified by an argument via%n. This functioning is occasionally used as a part of more elaborate format-string attacks.[26]

The%n functioning also makesprintf accidentallyTuring-complete even with a well-formed set of arguments. A game of tic-tac-toe written in the format string is a winner of the 27thIOCCC.[27]

Related functions

[edit]

Family

[edit]

Variants ofprintf in the C standard library include:fprintf outputs to afile instead of standard output.

sprintf writes to astring buffer instead of standard output.

snprintf provides a level of safety oversprintf since the caller provides a lengthn that is the length of the output buffer in bytes (including space for the trailing null character).

asprintf provides for safety by accepting a stringhandle (char**) argument. The functionallocates a buffer of sufficient size to contain the formatted text and outputs the buffer via the handle.

For each function of the family, including printf, there is also a variant that accepts a singleva_list argument rather than a variable list of arguments. Typically, these variants start with "v". For example:vprintf,vfprintf,vsprintf.

Generally, printf-like functions return the number of bytes output or -1 to indicate failure.[28]

Other contexts

[edit]

The following list includes notable programming languages that provide (directly or via a standard library) functioning that is the same or similar to the C printf-like functions. Excluded are languages that use format strings that deviate from the style in this article (such asAMPL andElixir), languages that inherit their implementation from theJava virtual machine (JVM) or other environment (such asClojure andScala), and languages that do not have a standard native printf implementation but have external libraries which emulate printf behavior (such asJavaScript).

See also

[edit]
  • "Hello, World!" program – A basic example program first featured inThe C Programming Language (the "K&R Book"), which in the C example uses printf to output the message "Hello, World!"
  • Format (Common Lisp) – Common Lisp function that produces formatted text
  • C standard library – Standard library for the C programming language
  • Format string attack – Type of software vulnerabilityPages displaying short descriptions of redirect targets
  • Input/output (C++) – C++ input/output functionality in the standard library
  • printf debugging – Fixing defects in an engineered systemPages displaying short descriptions of redirect targets
  • printf (Unix) – Shell command for formatting and outputting text; like printf() library function
  • printk – Printf-like function for the Linux kernel
  • scanf – Control parameter used in programming languages
  • string interpolation – Replacing placeholders in a string with values

Notes

[edit]
  1. ^According to the 1956 Fortran manual[1], thePRINT command prints on the attachedprinter. The manual also introduces the commandWRITEOUTPUTTAPE that also uses theFORMAT statement to write on atape unit.

References

[edit]
  1. ^abBackus, John Warner; Beeber, R. J.; Best, Sheldon F.; Goldberg, Richard; Herrick, Harlan L.; Hughes, R. A.; Mitchell, L. B.; Nelson, Robert A.;Nutt, Roy;Sayre, David; Sheridan, Peter B.; Stern, Harold; Ziller, Irving (15 October 1956).Sayre, David (ed.).The FORTRAN Automatic Coding System for the IBM 704 EDPM: Programmer's Reference Manual(PDF). New York, USA: Applied Science Division and Programming Research Department,International Business Machines Corporation. pp. 26–30.Archived(PDF) from the original on 4 July 2022. Retrieved4 July 2022. (2+51+1 pages)
  2. ^"BCPL".cl.cam.ac.uk. Retrieved19 March 2018.
  3. ^Richards, Martin; Whitby-Strevens, Colin (1979).BCPL - the language and its compiler. Cambridge University Press. p. 50.
  4. ^"Format String Attack".
  5. ^"iPhone Bug Breaks WiFi When You Join Hotspot With Unusual Name".
  6. ^"C++20 Standard format specification".
  7. ^McIlroy, M. D. (1987).A Research Unix reader: annotated excerpts from the Programmer's Manual, 1971–1986(PDF) (Technical report). CSTR. Bell Labs. 139.
  8. ^"printf (4.3+Reno BSD)".man.freebsd.org. Retrieved1 April 2024.
  9. ^"Class PrintStream". docs.oracle.com. Retrieved13 September 2025.
  10. ^"3.8 Options to Request or Suppress Warnings".GCC 14.2 Manual.Free Software Foundation. 2024. Retrieved12 February 2025.
  11. ^"How Not to Code: Beware of printf". 10 August 2016.
  12. ^"C++20 Format improvements proposal to enable compile-time checks".
  13. ^"C++20 std::format".
  14. ^"libfmt: a modern formatting library".
  15. ^"C++20 Text Formatting: An Introduction".
  16. ^"C++ Format Proposal History".
  17. ^"C++ print".
  18. ^"Text Parsing". www.open-std.org. 15 October 2024.
  19. ^"Format Specification Mini-Language".
  20. ^"printf".cplusplus.com. Retrieved10 June 2020.
  21. ^"7.19.6.1".ISO/IEC 9899:1999(E): Programming Languages – C (Technical report).ISO/IEC. 1999. para. 7.
  22. ^"Table of Output Conversions".The GNU C Library Reference Manual.Free Software Foundation. sec. 12.12.3. Retrieved17 March 2014.
  23. ^"printf"(%a added in C99)
  24. ^"Formatting Numeric Print Output".The Java Tutorials. Oracle Inc. Retrieved19 March 2018.
  25. ^Dunlap, Randy; Murray, Andrew (n.d.). "How to get printk format specifiers right".The Linux Kernel documentation (Report).Linux Foundation.Archived from the original on 6 February 2025. Retrieved12 February 2025.
  26. ^El-Sherei, Saif (20 May 2013)."Format String Exploitation Tutorial"(PDF).Exploit Database. Contributions by Haroon meer; Sherif El Deeb; Corelancoder; Dominic Wang.OffSec Services Limited. Retrieved12 February 2025.
  27. ^Carlini, Nicholas (2020)."printf machine".International Obfuscated C Code Contest. Judges: Leonid A. Broukhis, Landon Curt Noll. Landon Curt Noll. Retrieved12 February 2025.
  28. ^Kerrisk, Michael (2 February 2025)."sprintf(3) — Linux manual page".man7.org. Retrieved19 March 2025.
  29. ^"POSIX awk, Output Statements".The Open Group Base Specifications, Issue 7.pubs.opengroup.org (Technical report) (2018 ed.).The Open Group. Retrieved29 May 2022.
  30. ^"Printf Standard Library".The Julia Language Manual. Retrieved22 February 2021.
  31. ^"Built-in Types:printf-style String Formatting",The Python Standard Library, Python Software Foundation, retrieved24 February 2021
  32. ^"SQLite's Built-in printf()".sqlite.org. Retrieved24 November 2025.

External links

[edit]
Features
Standard library
Implementations
Compilers
IDEs
Comparison with
other languages
Descendant
languages
Designer
File system
Processes
User environment
Text processing
Shell builtins
Searching
Documentation
Software development
Miscellaneous
Retrieved from "https://en.wikipedia.org/w/index.php?title=Printf&oldid=1323890101"
Categories:
Hidden categories:

[8]ページ先頭

©2009-2025 Movatter.jp