- Printf
The class of printf functions (which stands for "print formatted") is a class of functions, typically associated with
curly bracket programming language s, that accept a string parameter (called the format string) which specifies a method for rendering a number of other parameters (of which there typically may be arbitrarily many, of a variety of types) into a string. Usually this string is then printed on thestandard output stream, but variants exist that perform other tasks with the result. Characters in the format string are usually copied literally into the function's output, with the other parameters being rendered into the resulting text at points marked by format specifiers, which are typically introduced by a % character. A literal percent sign can be copied into the output using theescape sequence %%.Timeline
Several
programming languages implement aprintf
function, to output a formatted string. It originated from the C programming language, where it has a prototype similar to the following:int printf(const char *format, ...)The string constant format
provides a description of the output, withplaceholder s marked by "%"escape character s, to specify both the relative location and the type of output that the function should produce.1950s: FORTRAN, COBOL
FORTRANs variadic
PRINT
statement took a reference to a non-executableFORMAT
statement.PRINT, 601, 123456, 1000.0, 3.14, 250 601 FORMAT (7HRED NUM,I7,3HEXP, E7.1, 4HREAL ,F3.2, 3HVAL, I3)
will print the following line (including the CF LF characters):
RED NUM 123456 EXP 1.0E 03 REAL 3.14 VAL 250
1960s: BCPL, ALGOL 68, Multics PL/I
C's variadic
printf
has its origins inBCPL 'swritef
function.ALGOL 68 Draft and Final report had the functionsinf
andoutf
, subsequently these were revised out of the original language and replaced with the now more familiarreadf
andprintf/writef
. printf(($"Color "g", number1 "6d,", number2 "4zd,", hex "16r2d,", float "-d.2d,", unsigned value"-3d"."l$, "red", 123456, 89, BIN 255, 3.14, 250));Multics has a standard function calledioa_
with a wide variety of control codes.call ioa_ ("Hello, ^a", "world"); 1970s: C, Lisp
printf("Color %s, number1 %d, number2 %05d, hex %x, float %5.2f, unsigned value %u. ", "red", 123456, 89, 255, 3.14, 250); will print the following line (including new-line character, ): Color red, number1 123456, number2 00089, hex ff, float 3.14, unsigned value 250. The
printf
function returns the number of characters printed, or a negative value if an output error occurs.Common Lisp has the
format
function.(format t "Hello, ~a" "world") prints
"Hello, world"
on the standard output stream. If the first argument isnil
, format returns the string to its caller. The first argument can also be any output stream.format
was introduced intoZetaLisp at M.I.T. in 1978, based on theMultics ioa_
, and was later adopted into the Common Lisp standard.1980s: perl
Perl also has aprintf
function.Common Lisp has a format function which acts according to the same principles asprintf
, but uses different characters for output conversion. TheGLib library containsg_print
, an implementation ofprintf
.Some
Unix systems have aprintf
program for use inshell script s. This can be used instead of echo in situations where the latter is not portable. For example:echo -n -e "$FOO $BAR"may be rewritten portably as: printf "%s %s" "$FOO" "$BAR" 1990s: PHP, Python, Java & Javascript
1991: Python's
%
operator hearkens toprintf
's syntax when interpolating the contents of a tuple. This operator can, for example, be used with theprint
statement:print "%s %s" % (foo,bar) 1995:
PHP also has theprintf
function, with the same specifications and usage as that in C/C++.MATLAB does not haveprintf
, but does have its two extensionssprintf
andfprintf
which use the same formatting strings.1995: Java supported
printf
from version 1.5 onwards as a member of thePrintStream
class, giving it the functionality of both theprintf
and
functions. This method is identical to thefprintf format
method in the same classes.System.out.printf("%s, %s", "Hello", "World!"); // Writes "Hello, World!" to standard outputThe String
class also includes aformat
method that returns a new string containing the formatted text, similar to the functionality ofasprintf
.Unlike most other implementations, Java's implementation ofprintf
throws an exception on encountering a malformed format string.1995:
JavaScript does not have aprintf
function, despite it being acurly bracket programming language .Derivative functions
The
C Standard specifies a number of derivative functions to further leverage the printf functionality:fprintf
int fprintf(FILE *stream, const char *format, ...) fprintf
enables printf output to be written to any file. Programmers frequently use it to print errors, by writing to the standard error device, but it can operate with any file opened with the
function.fopen printf
int sprintf (char *str, const char *format, ...) sprintf
prints to a string (char
array) instead of to standard output. Users ofsprintf
must ensure, via calculation or via aguard page , that the resulting string will not be larger than the memory allocated for "str". Failure to ensure this can allow abuffer overflow to occur.In higher-level languages such as
PHP thesprintf
function does not have thestr
argument. Instead, it returns the formatted output string. The prototype in PHP is like this:string sprintf (const string format, ...) Buffer safety and sprintf
In ISO C99,
snprintf
was introduced as an alternative tosprintf
that can help avoid the risk of a buffer overflow:int snprintf(char *str, size_t size, const char * restrict format, ...) snprintf
is guaranteed not to write more than "size" bytes into "str", so use of it can help avoid the risk of a buffer overflow, as in the following code fragment:
#define BUFFER_SIZE 50char buf [BUFFER_SIZE] ;int n;...
n = snprintf(buf, BUFFER_SIZE, "Your name is %s. ", username);if (n > BUFFER_SIZE) /* Handle error */If "username" in the above example exceeds 34 characters in length, the function will limit the string that gets saved in "buf" by cutting off final characters (truncating). This may seem undesirable, but it is usually preferable to having a security vulnerability, which
buffer overflows often cause. Additionally, the return code ofsnprintf
indicates how many characters the function "would" have written to the string had enough space existed. Systems can use this information to allocate a new (larger) buffer if they require the whole string.Another safe
sprintf
alternative isasprintf
which is a GNU extension:int asprintf(char **ret, const char *format, ...) asprintf
automatically allocates enough memory to hold the final string. It sets*ret
to a pointer to the resulting string, or to an undefined value if an error occurred (GLibc is notable in being the only implementation that doesn't always set*ret
toNULL on error). The programmer usingasprintf
has the responsibility of freeing the allocated memory after use. Though not part of any standard,asprintf
comes in the C libraries of several operating systems (includingOpenBSD ,FreeBSD , andNetBSD ) and on other platforms in thelibiberty library.GLib provides yet another safe alternative:g_strdup_printf
, which allocates enough memory, but, unlikeasprintf
, returns the resulting string as its return value rather than via the first argument.C++ alternatives to sprintf for numeric conversion
The standard method for string formatting and the conversion of other types to strings in C++ is
iostream . Unlike printf, the iostream standard library is type-safe and extensible.A common programming task is convert a numeric type into a string (char buffer). The
sprintf
family, while useful, in many applications seems like overkill for such a simple task.A number of alternative means in C/C++ have been developed:
* [http://boost.org/libs/conversion/lexical_cast.htm Boost::lexical_cast ]
* [http://www.boost.org/libs/format/index.html Boost::format ]
* [http://code.google.com/p/stringencoders/wiki/NumToA modp_numtoa]
*itoa vprintf, vfprintf, vsprintf, vsnprintf, and vasprintf
/* va_list versions of above */int vprintf(const char *format, va_list ap);int vfprintf(FILE *stream, const char *format, va_list ap);int vsprintf(char *str, const char *format, va_list ap);int vsnprintf(char *str, size_t size, const char *format, va_list ap);int vasprintf(char **ret, const char *format, va_list ap); These are analogous to the above functions without the "v"s, except that they use variable argument lists. These functions offer the ability for programmers to essentially create their own printf variants. For instance, a programmer could write a function
void fatal_error(const char *format, ...) which would use the
va_start
macro to obtain ava_list
variable from the extra parameters, print a message on the standard error device usingvfprintf
, clean up after theva_list
variable with theva_end
macro, and finally perform the necessary tasks to cleanly shut down the program.Another common application of these functions is to write a custom printf that prints to a different target than a file. For instance, a graphical library might provide a printf-like function with X and Y coordinates:
int graphical_printf(int x, int y, const char *format, ...) This would work by temporarily saving the string to a private buffer using
vsnprintf
orvasprintf
.printf format placeholders
Formatting takes place via placeholders within the format string. For example, if a program wanted to print out a person's age, it could present the output by prefixing it with "Your age is ". To denote that we want the integer for the age to be shown immediately after that message, we may use the format string: "Your age is %d."
The syntax for a format placeholder is "% [parameter] [flags] [width] [.precision] [length] type".
*Parameter can be omitted or can be::
*Precision can be omitted or be any of::
ISO C99 includes the
header file that includes a number of macros for use in platform-independentinttypes.h printf
coding. Example macros include::*Type can be any of::
If the
syntax of a conversion specification is invalid, behavior remains undefined, and in fact can cause program termination. If there are too fewfunction argument s provided to supply values for all the conversion specifications in the template string, or if the arguments are not of the correct types, the results are also undefined. Excess arguments are ignored. In a number of cases, the undefined behavior has led to "Format string attack " security vulnerabilities. Note that some compilers, like the GNU Compiler Collection, will statically check the format strings of printf-like functions and warn about problems (specially by using the flags-Wall
or-Wformat
)Risks of using field width versus explicit delimiters in tabular output
Using only field widths to provide for tabulation, as with a format like "
%8d%8d%8d
" for three integers in three 8-character columns, will not guarantee that field separation will be retained if large numbers occur in the data. Loss of field separation can easily lead to corrupt output. In systems which encourage the use of programs as building blocks in scripts, such corrupt data can often be forwarded into and corrupt further processing, regardless of whether the original programmer expected the output would only be read by human eyes. Such problems can be eliminated by including explicit delimiters, even spaces, in all tabular output formats. Simply changing the dangerous example from before to "%7d %7d %7d
" addresses this, formatting identically until numbers become larger, but then explicitly preventing them from becoming merged on output due to the explicitly-included spaces. Similar strategies apply to string data.Custom printf format placeholders
There are a few implementations of
printf
-like functions that allow extensions to the escape-character-based mini-language, thus allowing the programmer to have a specific formatting function for non-builtin types. One of the most well-known is glibc's[http://www.gnu.org/software/libc/manual/html_node/Customizing-Printf.html register_printf_function()]
. However, it is rarely used due to the fact that it conflicts with static format string checking. Another is [http://www.and.org/vstr/#cust-fmt Vstr custom formatters] , which allows adding multi-character format names, and can work with static format checkers.Some applications (like the
Apache HTTP Server ) include their ownprintf
-like function, and embed extensions into it. However these all tend to have the same problems thatregister_printf_function()
has.Most non-C languages that have a
printf
-like function work around the lack of this feature by just using the "%s
" format and converting the object to a string representation.C++ offers a notable exception, in that it has aprintf
function inherited from its C history, but also has a completely different mechanism that is preferred.Programming languages with printf
*
AMPL
*awk
*Bourne shell (sh) and derivatives such asKorn shell (ksh),Bourne again shell (bash), orZ shell (zsh)
*C programming language, and subsequentlyC++ andObj-C (C++ also provides overloaded shift operators and manipulators as an alternative for formatted output - seeiostream andiomanip )
*F Sharp (programming language)
*GNU Octave
*Java programming language (since version 1.5)
*Mathematica
*MATLAB
*Objective Caml
*PHP programming language, web-based inflected form of C
*Python programming language (using the % operator)
*Perl
*Ruby programming language
*Haskellee also
*
scanf
*C standard library
*Format string attack
*iostream External links
* [http://www.pixelbeat.org/programming/gcc/format_specs.html 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#syntaxFormatter
specification] in Java 1.5
* [http://bash-hackers.org/wiki/doku.php?id=commands:builtin:printf GNU Bashprintf(1)
builtin]
* [http://www.and.org/vstr/printf_comparison C printf comparison page]
*man|3|printf|OpenBSD|formatted output conversion
* [http://alexei.417.ro/blog/sprintf_for_javascript.htmlsprintf()
for JavaScript - a lightweight and easy to use implementation]
* [http://msdn.microsoft.com/en-us/library/tcxf1dw6(VS.71).aspx Size Prefixes forprintf
andwprintf
Format-Type Specifiers]
Wikimedia Foundation. 2010.