Printf

From Free net encyclopedia

Template:Lowercase

Several programming languages implement a printf 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, with placeholders marked by "%" escape characters, to specify both the relative location and the type of output that the function should produce.

For example in C

printf("Color: %s, some number: %d, some fancy number %05d, hexadecimal number %x, floating point number %5.2f.\n",
            "red", 123456, 89, 255, 3.14);

will print following line (including new-line character, \n):

Color: red, some number: 123456, some fancy number 00089, hexadecimal number ff, floating point number 3.14.

The printf function returns the number of characters printed, or a negative value if an output error occurred.

Perl also has a printf function. Common Lisp has a format function which acts according to the same principles as printf, but uses different characters for output conversion. Python has an analogue (as the % operator). The GLib library contains g_print, an implementation of printf. Some Unix systems have a printf program for use in shell scripts.

PHP also has the printf function, with the same specifications and usage as that in C/C++.

Contents

Derivative functions

ANSI C provides a number of derivative functions to gain further leverage from the printf functionality:

fprintf

int fprintf(FILE *stream, const char *format, ...)

fprintf enables printf output to be written to any file. Programmers most frequently use it to print errors, by writing to the standard error device, but it can also operate with any file opened with the fopen function.

sprintf

int sprintf (char *str, const char *format, ...)

sprintf prints to a string (char array) instead of to standard output. Users of sprintf must ensure, via calculation or via a guard page, that the resulting string will not be larger than the memory allocated for str. Failure to ensure this will allow a buffer overflow to occur.

It is notable that in PHP the sprintf function does not have the str argument. Instead, it returns the formatted output string. The prototype in PHP is like this:

string sprintf (const string format, ...)

As an alternative, many environments offer the snprintf function:

int snprintf(char *str, size_t size, const char *format, ...)

snprintf is guaranteed not to write more than size bytes into str, so programmers using it can avoid any risk of a buffer overflow, as in the following code snippet:

#define BUFFER_SIZE 50
char buf[BUFFER_SIZE];

...

snprintf(buf, BUFFER_SIZE, "Your name is %s.\n", username);

If username in the above example exceeds 50 characters in length, the function will limit the string that gets saved in buf by cutting off final characters (truncating). This may seem undesirable, yet preferable to having a security vulnerability, which buffer overflows can often lead to. Additionally, the return code of snprintf 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.

snprintf does not form part of the widely implemented ANSI C standard, as sprintf does. However, it came into the language for the later C99 standard and often existed in C libraries before that.

Another safe sprintf alternative is asprintf:

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 NULL if not enough memory was available. The programmer using asprintf 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 (including OpenBSD, FreeBSD, and NetBSD) and on other platforms in the libiberty library.

vprintf, vfprintf, vsprintf, vsnprintf, and vasprintf

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 vs, 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 a va_list variable from the extra parameters, print a message on the standard error device using vfprintf, clean up after the va_list variable with the va_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 or vasprintf.

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 "%[flags][width][.precision][length]type".

Where type can be any of:

  • 'd', 'i' : Print an integer as a signed decimal number. '%d' and '%i' are synonymous for output, but are different when used with scanf() function for input.
  • 'u' : Print decimal unsigned int, unsigned short, and unsigned char
  • 'f' : Print a floating-point number in normal (fixed-point) notation.
  • 'g', 'G' : Print a floating-point number in either normal or exponential notation, whichever is more appropriate for its magnitude. 'g' uses lower-case letters and 'G' uses upper-case.
  • 'x', 'X' : Print an integer as a hexadecimal number. 'x' uses lower-case letters and 'X' uses upper-case.
  • 's' : Print a character string.
  • 'c' : Print a character (char).
  • '%' : Print a literal '%' character.

Flags can be omitted or be any of:

  • '+' : Causes printf to always denote the sign '+' or '-' of a number (the default is to omit the sign for positive numbers). Only applicable to numeric types.
  • '-' : Causes printf to left-align the output of this placeholder (the default is to right-align the output).
  • '#' : Causes printf to output trailing zeroes in non-integer numeric types and causes hexadecial types to display a '0x' prefix.

Width can be omitted or be any of:

  • a number : Causes printf to pad the output of this placeholder with spaces until it is at least number characters wide.
  • '*' : Causes printf to pad the output until it is n characters wide, where n is an integer value stored in the next argument.

.Precision can be omitted or be any of:

  • a number : For non-integral numeric types, causes the decimal portion of the output to be expressed in at least number digits. For the string type, causes the output to be truncated at number characters.
  • '*' : Same as the above, but uses an integer value in the next argument to determine the number of decimal places or maximum string length.

Length can be omitted or be any of:

  • 'h' : For integer types, causes printf to expect a short integer argument.
  • 'l' : (ell) For integer types, causes printf to expect a long integer argument, for floating-point types, causes printf to expect a double precision floating-point argument.
  • 'll' : (ell ell) For integer types, causes printf to expect a long long integer argument.


If the syntax of a conversion specification is invalid, behavior remains undefined. If there are too few or extraneous function arguments 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. In a number of cases the undefined behavior has lead 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.

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 programer to have a specific formatting function for non-builtin types. One of the most well-known is glibc's register_printf_function(). However, it is rarely used due to the fact that it conflicts with static format string checking. Another is 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 own printf-like function, and embed extensions into it. However these all tend to have the same problems that register_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 a printf function inherited from its C history but instead has a completely different mechanism that is preferred.

Programming languages with printf

See also

External links

pl:printf