Open main menu
Home
Random
Recent changes
Special pages
Community portal
Preferences
About Wikipedia
Disclaimers
Incubator escapee wiki
Search
User menu
Talk
Dark mode
Contributions
Create account
Log in
Editing
Printf
Warning:
You are not logged in. Your IP address will be publicly visible if you make any edits. If you
log in
or
create an account
, your edits will be attributed to your username, along with other benefits.
Anti-spam check. Do
not
fill this in!
{{Short description|C function to format and output text}} {{More citations needed|date=February 2015}} {{Use dmy dates|date=January 2021}} {{Use American English|date=February 2025}} {{lowercase title|title=printf}} [[Image:Printf.svg|350px|thumb|alt=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 a [[C standard library]] [[Function (computer programming)|function]] that [[Content format|formats]] [[Plain text|text]] and writes it to [[standard output]]. The function accepts a format [[Null-terminated string|c-string]] [[Parameter (computer programming)|argument]] and a [[variadic|variable]] number of value arguments that the function [[serialization|serializes]] per the format string. Mismatch between the format specifiers and count and [[data type|type]] of values results in [[undefined behavior]] and possibly program [[Crash (computing)|crash]] or other [[Vulnerability (computing)|vulnerability]]. The format string is [[Semantics encoding|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 [[percent sign|{{code|%}}]] 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 programming contexts (i.e. [[programming languages|languages]]) with the same or similar [[Syntax (programming languages)|syntax]] and [[Semantics (computer science)|semantics]]. The [[scanf]] C standard library function complements printf by providing formatted input (a.k.a. [[Lexical analysis|lexing]], a.k.a. [[parsing]]) via a similar format string syntax. The name, ''printf'', is short for ''print formatted'' where ''print'' refers to output to a [[computer printer|printer]] although the function is not limited to printer output. Today, print refers to output to any text-based environment such as a [[computer terminal|terminal]] or a [[computer file|file]]. ==History== ===1950s: Fortran=== Early programming languages like [[Fortran]] used special statements with different syntax from other calculations to build formatting descriptions.<ref name="Sayre_1956">{{cite book |title=The FORTRAN Automatic Coding System for the IBM 704 EDPM: Programmer's Reference Manual |publisher=Applied Science Division and Programming Research Department, [[International Business Machines Corporation]] |location=New York, USA |date=October 15, 1956 |editor-first=David |editor-last=Sayre |editor-link=David Sayre |author-first1=John Warner |author-last1=Backus |author-link1=John Warner Backus |author-first2=R. J. |author-last2=Beeber |author-first3=Sheldon F. |author-last3=Best |author-first4=Richard |author-last4=Goldberg |author-first5=Harlan L. |author-last5=Herrick |author-first6=R. A. |author-last6=Hughes |author-first7=L. B. |author-last7=Mitchell |author-first8=Robert A. |author-last8=Nelson |author-first9=Roy |author-last9=Nutt |author-link9=Roy Nutt |author-first10=David |author-last10=Sayre |author-link10=David Sayre |author-first11=Peter B. |author-last11=Sheridan |author-first12=Harold |author-last12=Stern |author-first13=Irving |author-last13=Ziller |pages=26β30 |url=http://archive.computerhistory.org/resources/text/Fortran/102649787.05.01.acc.pdf |access-date=July 4, 2022 |url-status=live |archive-url=https://web.archive.org/web/20220704193549/http://archive.computerhistory.org/resources/text/Fortran/102649787.05.01.acc.pdf |archive-date=July 4, 2022}} (2+51+1 pages)</ref> In this example, the format is specified on line {{samp|601}}, and the {{code|PRINT|fortran}}{{efn|According to the 1956 Fortran manual{{r|Sayre_1956}}, the {{code|PRINT|fortran}} command prints on the attached [[line printer|printer]]. The manual also introduces the command {{code|WRITE OUTPUT TAPE|fortran}} that also uses the {{code|FORMAT|fortran}} statement to write on a [[Magnetic-tape data storage|tape unit]].}} command refers to it by line number: <syntaxhighlight lang="fortranfixed"> PRINT 601, IA, IB, AREA 601 FORMAT (4H A= ,I5,5H B= ,I5,8H AREA= ,F10.2, 13H SQUARE UNITS) </syntaxhighlight> Hereby: * {{code|4H|fortran}} indicates a [[String (computer science)|string]] of 4 [[character (computer science)|characters]] <code>" A= "</code> ({{code|H}} means [[Hollerith constant|Hollerith Field]]); * {{code|I5|fortran}} indicates an [[Integer (computer science)|integer]] field of width 5; * {{code|F10.2|fortran}} indicates a [[floating-point]] field of width 10 with 2 digits after the decimal point. An output with input arguments {{code|100}}, {{code|200}}, and {{code|1500.25}} might look like this: <syntaxhighlight lang="output"> A= 100 B= 200 AREA= 1500.25 SQUARE UNITS </syntaxhighlight> ===1960s: BCPL and ALGOL 68=== <!-- Question: did the BCPL writef library routine already appear in 1967... or only later? --> In 1967, [[BCPL]] appeared.<ref>{{cite web|url=http://www.cl.cam.ac.uk/users/mr/BCPL.html|title=BCPL|website=cl.cam.ac.uk|access-date=19 March 2018}}</ref> Its library included the {{code|writef}} routine.<ref>{{cite book |last1=Richards |first1=Martin |last2=Whitby-Strevens |first2=Colin |title=BCPL - the language and its compiler |date=1979 |publisher=Cambridge University Press |page=[https://archive.org/details/richards1979bcpl/page/n57 50] |url=https://archive.org/details/richards1979bcpl}}</ref> An example application looks like this: <syntaxhighlight lang="text"> WRITEF("%I2-QUEENS PROBLEM HAS %I5 SOLUTIONS*N", NUMQUEENS, COUNT) </syntaxhighlight> Hereby: * {{code|%I2}} indicates an [[Integer (computer science)|integer]] of width 2 (the order of the format specification's field width and type is reversed compared to C's {{code|printf}}); * {{code|%I5}} indicates an integer of width 5; * {{code|*N}} is a BCPL ''language'' [[escape sequence]] representing a [[newline]] character (for which C uses the escape sequence {{code|\n}}). In 1968, [[ALGOL 68]] had a more function-like [[API]], but still used special syntax (the {{code|$}} delimiters surround special formatting syntax): <syntaxhighlight lang="cpp"> printf(($"Color "g", number1 "6d,", number2 "4zd,", hex "16r2d,", float "-d.2d,", unsigned value"-3d"."l$, "red", 123456, 89, BIN 255, 3.14, 250)); </syntaxhighlight> In contrast to Fortran, using normal function calls and data types simplifies the language and compiler, and allows the implementation of the input/output to be written in the same language. These advantages were thought to outweigh the disadvantages (such as a complete lack of [[type 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<ref>{{cite web|url=https://owasp.org/www-community/attacks/Format_string_attack |title = Format String Attack}}</ref> 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"<ref>{{cite web|url=https://www.bleepingcomputer.com/news/security/iphone-bug-breaks-wifi-when-you-join-hotspot-with-unusual-name/|title = iPhone Bug Breaks WiFi When You Join Hotspot With Unusual Name}}</ref>). Modern languages, such as [[C++20]] and later, tend to include format specifications as a part of the language syntax,<ref>{{cite web|url=https://en.cppreference.com/w/cpp/utility/format/spec|title=C++20 Standard format specification}}</ref> 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=== In 1973, {{code|printf}} was included as a C standard library routine as part of [[Version 4 Unix]].<ref name="reader">{{cite tech report |first1=M. D. |last1=McIlroy |author-link1=Doug McIlroy |year=1987 |url=http://www.cs.dartmouth.edu/~doug/reader.pdf |title=A Research Unix reader: annotated excerpts from the Programmer's Manual, 1971β1986 |series=CSTR |number=139 |institution=Bell Labs}}</ref> ===1990s: Shell command=== In 1990, the <code>[[printf (Unix)|printf]]</code> [[shell (computing)|shell]] [[command (computing)|command]], modeled after the C standard library function, was included with [[4.3BSD-Reno]].<ref>{{cite web |title=printf (4.3+Reno BSD) |url=https://man.freebsd.org/cgi/man.cgi?query=printf&apropos=0&sektion=0&manpath=4.3BSD+Reno&arch=default&format=html |website=man.freebsd.org |access-date=2024-04-01}}</ref> In 1991, a {{code|printf}} command was included with GNU shellutils (now part of [[GNU Core Utilities]]). ===2000s: -Wformat safety=== The need to do something about the range of problems resulting from lack of type safety has prompted attempts to make the C++ compiler {{code|printf}}-aware. The {{kbd|-Wformat}} option of [[GNU Compiler Collection|GCC]] allows compile-time checks to {{code|printf}} calls, enabling the compiler to detect a subset of invalid calls (and issue either a warning or an error, stopping the compilation altogether, depending on other flags).<ref>{{cite manual| section-url= https://gcc.gnu.org/onlinedocs/gcc-14.2.0/gcc/Warning-Options.html#index-Wformat | url= https://gcc.gnu.org/onlinedocs/gcc-14.2.0/gcc/ | section= 3.8 Options to Request or Suppress Warnings | title= GCC 14.2 Manual | author=Free Software Foundation | author-link=Free Software Foundation | publisher= self-published | year= 2024 | accessdate= 2025-02-12 }}</ref> Since the compiler is inspecting {{code|printf}} format specifiers, enabling this effectively extends the C++ syntax by making formatting a part of it. ===2020s: std::print === To address usability issues with the existing [[C++]] [[input/output (C++)|input/output support]], as well as avoid safety issues of printf<ref>{{cite web|url=https://hownot2code.wordpress.com/2016/08/10/beware-of-printf|title=How Not to Code: Beware of printf|date=10 August 2016 }}</ref> the [[C++ standard library]] was revised<ref>{{cite web|url=https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2021/p2216r2.html|title=C++20 Format improvements proposal to enable compile-time checks}}</ref> to support a new type-safe formatting starting with [[C++20]].<ref>{{cite web|url=https://en.cppreference.com/w/cpp/utility/format/format|title=C++20 std::format}}</ref> The approach of {{code|std::format|cpp}} resulted from incorporating Victor Zverovich's {{code|libfmt}}<ref>{{cite web|url=https://fmt.dev|title=libfmt: a modern formatting library}}</ref> API into the language specification<ref>{{cite web|url=https://www.accu.org/journals/overload/29/166/collyer/|title=C++20 Text Formatting: An Introduction}}</ref> (Zverovich wrote<ref>{{cite web|url=https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2019/p0645r10.html|title=C++ Format Proposal History}}</ref> the first draft of the new format proposal); consequently, {{code|libfmt}} is an implementation of the C++20 format specification. In [[C++23]], another function, {{code|std::print|cpp}}, was introduced that combines formatting and outputting and therefore is a functional replacement for {{code|printf()}}.<ref>{{cite web|url=https://en.cppreference.com/w/cpp/io/print|title=C++ print}}</ref> 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 {{kbd|-Wformat}} option, this is not an optional feature. The format specification of {{code|libfmt}} and {{code|std::format|cpp}} is, in itself, an extensible "mini-language" (referred to as such in the specification),<ref>{{cite web|url=https://fmt.dev/6.2.1/syntax.html#format-specification-mini-language|title=Format Specification Mini-Language}}</ref> an example of a [[domain-specific language]]. As such, {{code|std::print|cpp}}, completes a historical cycle; bringing the state-of-the-art (as of 2024) back to what it was in the case of Fortran's first {{code|PRINT|fortran}} implementation in the 1950s<!--overly colorful and debatable-->. == Format specifier == Formatting of a value is specified as markup in the format string. For example, the following outputs <code>Your age is</code> and then the value of the variable {{var|age}} in decimal format. <syntaxhighlight lang="c"> printf("Your age is %d", age); </syntaxhighlight> ===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 {{em|not}} sequential. The numeric value {{samp|n}} selects the n-th value parameter. This is a [[POSIX]] extension; not [[C99]].{{needs citation|date=April 2025}} {{Table alignment}} {| class="wikitable col1center" |- ! Text ! Description |- | {{tt|''n''$}} | ''n'' is the index of the value parameter to [[serialization|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, <syntaxhighlight lang="c"> printf("%2$d %2$#x; %1$d %1$#x",16,17); </syntaxhighlight> outputs: {{samp|17 0x11; 16 0x10}} This field is particularly useful for [[Localization (computing)|localizing]] messages to different [[natural language]]s that use different [[word order]]s. In [[Microsoft Windows API|Windows API]], support for this feature is via a different function, {{code|printf_p}}. ===Flags field=== The flags field can be zero or more of (in any order): {{Table alignment}} {| class="wikitable col1center" |- ! Text ! Description |- | {{tt|-}} |Left-align the output of this placeholder; default is to right-align the output |- | {{tt|+}} |Prepends a plus sign for a positive value; by default a positive value does not have a prefix |- | <code style="white-space:pre"> </code><br />(space) |Prepends a space character for a positive value; ignored if the {{tt|+}} flag exists; by default a positive value does not have a prefix |- | {{tt|0}} |When the 'width' option is specified, prepends zeros for numeric types; by prepends spaces; for example, {{code|printf("%4X",3)|c}} produces <samp style="white-space:pre">" 3"</samp>, while {{code|printf("%04X",3);|c}} produces {{samp|"0003"}} |- | {{tt|'}} | The integer or exponent of a decimal has the thousands grouping separator applied |- | {{tt|#}} | Alternate form:<br /> For {{tt|g}} and {{tt|G}} types, trailing zeros are not removed<br /> For {{tt|f}}, {{tt|F}}, {{tt|e}}, {{tt|E}}, {{tt|g}}, {{tt|G}} types, the output always contains a decimal point<br /> For {{tt|o}}, {{tt|x}}, {{tt|X}} types, the text {{tt|0}}, {{tt|0x}}, {{tt|0X}}, respectively, is prepended to non-zero numbers |} ===Width field=== The width field specifies the {{em|minimum}} 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, {{code|printf("%3d", 12);|c}} specifies a width of 3 and outputs {{samp|12}} with a space on the left to output 3 characters. The call {{code|printf("%3d", 1234);|c}} outputs {{samp|1234}} 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 {{code|*}}, then the width value is read from the list of values in the call.<ref>{{cite web |title=printf |url=http://www.cplusplus.com/reference/cstdio/printf/ |access-date=2020-06-10 |website=cplusplus.com}}</ref> For example, {{code|printf("%*d", 3, 10);|c}} outputs <samp style="white-space:pre"> 10</samp> where the second parameter, {{code|3|c}}, is the width (matches with {{code|*}}) and {{code|10|c}} is the value to [[serialization|serialize]] (matches with {{code|d}}). 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 {{code|-}} 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 ({{samp|1234}}) does not fit in the first column of width 3 and therefore the column is not aligned. <syntaxhighlight lang="output"> 1 1 12 12 123 123 1234 123 </syntaxhighlight> ===Precision field=== The precision field usually specifies a {{em|maximum}} limit of the output, depending on the particular 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 {{code|%g}} and {{code|%G}} it specifies the total number of [[significant digits]] (before and after the decimal, not including leading or trailing zeroes) to round to. For the [[string (computer science)|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 ({{code|*}}). For example, {{code|printf("%.*s", 3, "abcdef");|c}} outputs {{samp|abc}}. ===Length field=== The length field can be omitted or be any of: {{Table alignment}} {| class="wikitable col1center" |- ! Text ! Description |- | {{tt|hh}} | For integer types, causes {{tt|printf}} to expect an {{tt|int}}-sized integer argument which was promoted from a {{tt|char}}. |- | {{tt|h}} | For integer types, causes {{tt|printf}} to expect an {{tt|int}}-sized integer argument which was promoted from a {{tt|short}}. |- | {{tt|l}} | For integer types, causes {{tt|printf}} to expect a {{tt|long}}-sized integer argument. For floating-point types, this is ignored. {{tt|float}} arguments are always promoted to {{tt|double}} when used in a [[varargs]] call.<ref name="c99io">{{cite standard| publisher= [[International Organization for Standardization|ISO]]/[[International Electrotechnical Commission|IEC]] | year= 1999 | title-link= C99 | title= ISO/IEC 9899:1999(E): Programming Languages β C | section= 7.19.6.1 | at= para. 7 }}</ref> |- | {{tt|ll}} | For integer types, causes {{tt|printf}} to expect a {{tt|long long}}-sized integer argument. |- | {{tt|L}} | For floating-point types, causes {{tt|printf}} to expect a {{tt|long double}} argument. |- | {{tt|z}} | For integer types, causes {{tt|printf}} to expect a {{tt|size_t}}-sized integer argument. |- | {{tt|j}} | For integer types, causes {{tt|printf}} to expect a {{tt|intmax_t}}-sized integer argument. |- | {{tt|t}} | For integer types, causes {{tt|printf}} to expect a {{tt|ptrdiff_t}}-sized integer argument. |} Platform-specific length options came to exist prior to widespread use of the ISO C99 extensions, including: {{Table alignment}} {| class="wikitable col1center" |- ! Text ! Description ! ''Commonly found platforms'' |- | {{tt|I}} | For signed integer types, causes {{tt|printf}} to expect {{tt|ptrdiff_t}}-sized integer argument; for unsigned integer types, causes {{tt|printf}} to expect {{tt|size_t}}-sized integer argument. || [[Win32]]/[[Win64]] |- | {{tt|I32}} | For integer types, causes {{tt|printf}} to expect a 32-bit ([[double word]]) integer argument. || Win32/Win64 |- | {{tt|I64}} | For integer types, causes {{tt|printf}} to expect a 64-bit (quad word) integer argument. || Win32/Win64 |- | {{tt|q}} | For integer types, causes {{tt|printf}} to expect a 64-bit (quad word) integer argument. || [[BSD]] |} ISO C99 includes the <code>[[inttypes.h]]</code> header file that includes a number of [[Macro (computer science)|macros]] for platform-independent {{code|printf}} coding. For example: {{code|printf("%" PRId64, t);|c}} specifies decimal format for a [[Integer (computer science)|64-bit signed integer]]. Since the macros evaluate to a [[string literal]], and the compiler [[concatenates]] adjacent string literals, the expression {{code|"%" PRId64|c}} compiles to a single string. Macros include: {| class="wikitable" |- ! Macro ! Description |- | {{tt|PRId32}} | Typically equivalent to {{tt|I32d}} (''Win32/Win64'') or {{tt|d}} |- | {{tt|PRId64}} | Typically equivalent to {{tt|I64d}} (''Win32/Win64''), {{tt|lld}} (''32-bit platforms'') or {{tt|ld}} (''64-bit platforms'') |- | {{tt|PRIi32}} | Typically equivalent to {{tt|I32i}} (''Win32/Win64'') or {{tt|i}} |- | {{tt|PRIi64}} | Typically equivalent to {{tt|I64i}} (''Win32/Win64''), {{tt|lli}} (''32-bit platforms'') or {{tt|li}} (''64-bit platforms'') |- | {{tt|PRIu32}} | Typically equivalent to {{tt|I32u}} (''Win32/Win64'') or {{tt|u}} |- | {{tt|PRIu64}} | Typically equivalent to {{tt|I64u}} (''Win32/Win64''), {{tt|llu}} (''32-bit platforms'') or {{tt|lu}} (''64-bit platforms'') |- | {{tt|PRIx32}} | Typically equivalent to {{tt|I32x}} (''Win32/Win64'') or {{tt|x}} |- | {{tt|PRIx64}} | Typically equivalent to {{tt|I64x}} (''Win32/Win64''), {{tt|llx}} (''32-bit platforms'') or {{tt|lx}} (''64-bit platforms'') |} ===Type field=== The type field can be any of: {{Table alignment}} {| class="wikitable col1center" |- ! Text ! Description |- | {{tt|%}} |Output a literal {{tt|%}} character; does not accept flags, width, precision or length fields |- | {{tt|d}}, {{tt|i}} |(signed) {{tt|int}} formatted as decimal; {{tt|%d}} and {{tt|%i}} are synonymous except when used with <code>scanf</code> |- | {{tt|u}} | {{tt|unsigned int}} formatted as decimal. |- | {{tt|f}}, {{tt|F}} |{{tt|double}} formatted as [[Fixed-point arithmetic|fixed-point]]; {{tt|f}} and {{tt|F}} only differs in how the strings for an infinite number or [[NaN]] are printed ({{tt|inf}}, {{tt|infinity}} and {{tt|nan}} for {{tt|f}}; {{tt|INF}}, {{tt|INFINITY}} and {{tt|NAN}} for {{tt|F}}) |- | {{tt|e}}, {{tt|E}} |{{tt|double}} formatted as in exponential notation {{tt|''d''.''ddd''eΒ±''dd''}}; {{tt|E}} results in {{tt|E}} rather than {{tt|e}} to introduce the exponent; the exponent always contains at least two digits; if the value is zero, the exponent is {{tt|00}}; in Windows, the exponent contains three digits by default, e.g. {{tt|1.5e002}}, but this can be altered by Microsoft-specific {{code|_set_output_format}} function |- | {{tt|g}}, {{tt|G}} |{{tt|double}} formatted as either fixed-point or exponential notation, whichever is more appropriate for its magnitude; {{tt|g}} uses lower-case letters, {{tt|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 |- | {{tt|x}}, {{tt|X}} |{{tt|unsigned int}} formatted as [[hexadecimal]]; {{tt|x}} uses lower-case letters and {{tt|X}} uses upper-case |- | {{tt|o}} |{{tt|unsigned int}} formatted as [[octal]] |- | {{tt|s}} |null-terminated string |- | {{tt|c}} |{{tt|char}} |- | {{tt|p}} |[[Pointer (computer science)|Pointer]] formatted in an implementation-defined way |- | {{tt|a}}, {{tt|A}} |{{tt|double}} in hexadecimal notation, starting with {{tt|0x}} or {{tt|0X}}. {{tt|a}} uses lower-case letters, {{tt|A}} uses upper-case letters<ref>{{cite web| url= https://www.gnu.org/software/libc/manual/html_node/Table-of-Output-Conversions.html | work= The GNU C Library Reference Manual | at= sec. 12.12.3 | title= Table of Output Conversions | author= Free Software Foundation | author-link= Free Software Foundation | publisher= self-published | access-date=2014-03-17 }}</ref><ref> [http://www.cplusplus.com/reference/cstdio/printf/ "printf"] ({{tt|%a}} added in C99) </ref> |- | {{tt|n}} | Outputs nothing but writes the number of characters written so far into an integer [[Pointer (computer science)|pointer]] parameter; in [[Java (programming language)|Java]] this prints a [[newline]]<ref>{{cite web|url=https://docs.oracle.com/javase/tutorial/java/data/numberformat.html|title=Formatting Numeric Print Output |website=The Java Tutorials | publisher=Oracle Inc.|access-date=19 March 2018}}</ref> |} === Custom data type formatting === A common way to handle formatting with a custom data type is to format the custom data type value into a [[string (computer science)|string]], then use the {{code|%s|c}} specifier to include the serialized value in a larger message. Some printf-like functions allow extensions to the [[escape-character]]-based [[mini-language]], thus allowing the programmer to use a specific formatting function for non-builtin types. One is the (now [[deprecated]]) [[glibc]]'s [https://www.gnu.org/software/libc/manual/html_node/Customizing-Printf.html {{code|register_printf_function()}}]. However, it is rarely used due to the fact that it conflicts with [[static program analysis|static format string checking]]. Another is [http://www.and.org/vstr/#cust-fmt Vstr custom formatters], which allows adding multi-character format names. Some applications (like the [[Apache HTTP Server]]) include their own printf-like function, and embed extensions into it. However these all tend to have the same problems that {{code|register_printf_function()}} has. The [[Linux kernel]] <code>[[printk]]</code> function supports a number of ways to display kernel structures using the generic {{code|%p|c}} specification, by {{em|appending}} additional format characters.<ref>{{cite web | url= https://docs.kernel.org/core-api/printk-formats.html | title= How to get printk format specifiers right | work = The Linux Kernel documentation | first1= Randy | last1= Dunlap | first2= Andrew | last2= Murray | publisher= [[Linux Foundation]] | date= n.d. | access-date= 2025-02-12 | archive-date= 2025-02-06 | archive-url= https://web.archive.org/web/20250206200419/https://docs.kernel.org/core-api/printk-formats.html | url-status= live }}</ref> For example, {{code|%pI4|c}} prints an [[IPv4 address]] in dotted-decimal form. This allows static format string checking (of the {{code|%p|c}} portion) at the expense of full compatibility with normal printf. ==Vulnerabilities== === Format string attack === 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 the [[format string attack]]. Generally, for C, arguments are [[Call stack|passed 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, like [[GNU Compiler Collection|the GNU Compiler Collection]], will [[static program analysis|statically check]] the format strings of printf-like functions and warn about problems (when using the flags {{kbd|-Wall}} or {{kbd|-Wformat}}). GCC will also warn about user-defined printf-style functions if the non-standard "format" {{code|__attribute__}} is applied to the function. ===Uncontrolled format string exploit=== The format string is often a [[string literal]], which allows [[static program analysis|static analysis]] of the function call. However, the format string can be the value of a [[variable (programming)|variable]], which allows for dynamic formatting but also a security vulnerability known as an [[uncontrolled format string]] exploit. ===Memory write=== Although an output function on the surface, {{code|printf}} allows writing to a memory location specified by an argument via {{code|%n|c}}. This functionality is occasionally used as a part of more elaborate format-string attacks.<ref>{{cite web| url= https://www.exploit-db.com/docs/english/28476-linux-format-string-exploitation.pdf | title= Format String Exploitation Tutorial | website= [[ExploitDB|Exploit Database]] | date= 2013-05-20 | accessdate= 2025-02-12 | first= Saif | last= El-Sherei | others= <!-- names as formatted in source; leave as written --> Contributions by Haroon meer; Sherif El Deeb; Corelancoder; Dominic Wang | publisher= [[OffSec Services Limited]] }}</ref> The {{code|%n|c}} functionality also makes {{code|printf}} accidentally [[Turing-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 27th [[IOCCC]].<ref>{{cite web | url= https://www.ioccc.org/2020/carlini/index.html | title= printf machine | website= [[International Obfuscated C Code Contest]] | first= Nicholas | last= Carlini | author-link = Nicholas Carlini | others= Judged by Leonid A. Broukhis and Landon Curt Noll | publisher= Landon Curt Noll | year= 2020 | accessdate= 2025-02-12 }}</ref> ==Related functions== ===Family=== Variants of {{code|printf}} in the C standard library include: {{code|fprintf}} outputs to a [[File (computing)|file]] instead of standard output. {{code|sprintf}} writes to a [[string buffer]] instead of standard output. {{code|snprintf}} provides a level of safety over {{code|sprintf}} since the caller provides a length ''n'' that is the length of the output buffer in bytes (including space for the trailing nul). {{code|asprintf}} provides for safety by accepting a string [[Handle (computing)|handle]] (char**) argument. The function [[memory allocation|allocates]] 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 single [[va list|{{code|va_list}}]] argument rather than a variable list of arguments. Typically, these variants start with "v". For example: {{code|vprintf}}, {{code|vfprintf}}, {{code|vsprintf}}. Generally, printf-like functions return the number of bytes output or -1 to indicate failure.<ref>{{cite web | last=Kerrisk| first=Michael |date=Feb 2, 2025 |title=sprintf(3) β Linux manual page |website=man7.org |url=https://man7.org/linux/man-pages/man3/sprintf.3.html |access-date=Mar 19, 2025}}</ref> ===Other contexts=== The following list includes notable programming languages that provide (directly or via a standard library) functionality 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 as [[AMPL]] and [[Elixir (programming language)|Elixir]]), languages that inherit their implementation from the [[JVM]] or other environment (such as [[Clojure]] and [[Scala (programming language)|Scala]]), and languages that do not have a standard native printf implementation but have external libraries which emulate printf behavior (such as [[JavaScript]]). {{div col}} *[[awk]]<ref>{{cite standard| url=https://pubs.opengroup.org/onlinepubs/9699919799/utilities/awk.html#tag_20_06_13_10 |title="The Open Group Base Specifications Issue 7, 2018 edition", "POSIX awk", "Output Statements" | website=pubs.opengroup.org | publisher= [[The Open Group]] | access-date=2022-05-29}}</ref> *[[C (programming language)|C]] *[[C++]] *[[D (programming language)|D]] *[[F Sharp (programming language)|F#]] *[[LabVIEW|G]] *[[GNU Linear Programming Kit|GNU MathProg]] *[[GNU Octave]] *[[Go (programming language)|Go]] *[[Haskell programming language|Haskell]] *[[J (programming language)|J]] *[[Java (programming language)|Java]] (since version 1.5) and JVM languages *[[Julia (programming language)|Julia]] (via Printf standard library<ref>{{cite web |title=Printf Standard Library |url=https://docs.julialang.org/en/v1/stdlib/Printf/ |website=The Julia Language Manual |access-date=22 February 2021}}</ref>) *[[Lua (programming language)|Lua]] ({{code|string.format|lua}}) *[[Maple (software)|Maple]] *[[MATLAB]] *[[Max (software)|Max]] (via the {{code|sprintf}} object) *[[Objective-C]] *[[OCaml]] (via the Printf module) *[[PARI/GP]] *[[Perl]] *[[PHP]] *[[Python (programming language)|Python]] (via {{code|%|python}} operator)<ref>{{citation |title=The Python Standard Library |section=Built-in Types: <code>printf</code>-style String Formatting |publisher=Python Software Foundation |section-url=https://docs.python.org/library/stdtypes.html#old-string-formatting |access-date=2021-02-24}}</ref> *[[R (programming language)|R]] *[[Raku (programming language)|Raku]] (via {{code|printf|raku}}, {{code|sprintf|raku}}, and {{code|fmt|raku}}) *[[Red (programming language)|Red/System]] *[[Ruby (programming language)|Ruby]] *[[Tcl]] (via {{code|format}} command) *[[Transact-SQL]] (via [https://technet.microsoft.com/en-us/library/ms175014.aspx {{code|xp_sprintf}}]) *[[Vala (programming language)|Vala]] (via {{code|print()}} and {{code|FileStream.printf()}}) {{div col end}} ==See also== * [["Hello, World!" program]]{{snd}} A basic example program first featured in ''The C Programming Language'' (the "K&R Book"), which in the C example uses printf to output the message "Hello, World!" * {{Annotated link |Format (Common Lisp)}} * {{Annotated link |C standard library}} * {{Annotated link |Format string attack}} * {{Annotated link |iostream|{{code|std::iostream|cpp}}}} * {{Annotated link |ML (programming language)}} * {{Annotated link |printf debugging}} * {{Annotated link |printf (Unix)|{{code|printf}} (Unix)}} * {{Annotated link |printk|{{code|printk}}}} * {{Annotated link |scanf|{{code|scanf}}}} * {{Annotated link |string interpolation}} ==Notes== {{notelist}} ==References== {{Reflist|30em}} ==External links== *[http://en.cppreference.com/w/cpp/io/c/fprintf C++ reference for {{code|std::fprintf|cpp}}] *[http://www.pixelbeat.org/programming/gcc/format_specs.html gcc printf format specifications quick reference] *{{man|sh|printf|SUS|print formatted output}} *The [http://java.sun.com/j2se/1.5.0/docs/api/java/util/Formatter.html {{code|Formatter|java}} specification] in [[Java 1.5]] *[[GNU Bash]] [http://wiki.bash-hackers.org/commands/builtin/printf {{code|printf(1)}} builtin] {{CProLang}} {{Unix commands}} [[Category:Articles with example C code]] [[Category:Articles with example ALGOL 68 code]] [[Category:Articles with example Fortran code]] [[Category:C standard library]] [[Category:Unix software]]
Edit summary
(Briefly describe your changes)
By publishing changes, you agree to the
Terms of Use
, and you irrevocably agree to release your contribution under the
CC BY-SA 4.0 License
and the
GFDL
. You agree that a hyperlink or URL is sufficient attribution under the Creative Commons license.
Cancel
Editing help
(opens in new window)
Pages transcluded onto the current version of this page
(
help
)
:
Template:Annotated link
(
edit
)
Template:CProLang
(
edit
)
Template:Citation
(
edit
)
Template:Cite book
(
edit
)
Template:Cite manual
(
edit
)
Template:Cite standard
(
edit
)
Template:Cite tech report
(
edit
)
Template:Cite web
(
edit
)
Template:Code
(
edit
)
Template:Div col
(
edit
)
Template:Div col end
(
edit
)
Template:Efn
(
edit
)
Template:Em
(
edit
)
Template:Kbd
(
edit
)
Template:Lowercase title
(
edit
)
Template:Man
(
edit
)
Template:More citations needed
(
edit
)
Template:Needs citation
(
edit
)
Template:Notelist
(
edit
)
Template:Reflist
(
edit
)
Template:Samp
(
edit
)
Template:Short description
(
edit
)
Template:Snd
(
edit
)
Template:Table alignment
(
edit
)
Template:Tt
(
edit
)
Template:Unix commands
(
edit
)
Template:Use American English
(
edit
)
Template:Use dmy dates
(
edit
)
Template:Var
(
edit
)