Format specifier


Full syntax for format specifier is %[flags][width][.precision][length]type


Flags field may have zero or more characters, and in any order. List of supported flags:



minus -

Left-align the output of this placeholder. The default is to right-align the output

plus +

Prepends a plus for positive signed-numeric types. positive = +, negative = -

space space ch

Prepends a space for positive signed-numeric types. positive = space ch, negative = -. This flag is ignored if the + flag exists

zero 0

When the width option is specified, prepends zeros for numeric types. The default prepends spaces, if this flag is not set

apostrophe '

The integer or exponent of a decimal has the thousands grouping separator applied.

has #

Alternate form: For g and G types, trailing zeros are not removed. For f, F, e, E, g, G types, the output always contains a decimal point. For o, x, X types, the text 0, 0x, 0X, respectively, is prepended to non-zero numbers.


Width field specifies a minimum number of characters to output, and is typically used to pad fixed-width fields in tabulated output, where fields would otherwise be smaller. Please keep in mind that this parameter does not truncate output is input is longer than width field value.

Concerning width field, you may:

  • Ignore it completely, output does not rely on width field by any means

  • Write a fixed value as part of format specifier. Number must be an integer value

  • Use asterisk * char and pass number as part of parameter. printf("%3d", 6) or printf("%*d", 3, 6) will generate the same output.


When fixed value is used to set width field, leading zero is not counted as part of width field, but as flag instead, indicating prepend number with leading zeros


Precision field usually specifies a maximum limit on 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 that the output should be rounded. For the string type, it limits the number of characters that should be output, after which the string is truncated.

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") will result in abc being printed.


Length field may be ignored or one of the below:




For integer types, causes printf to expect an int-sized integer argument which was promoted from a char


For integer types, causes printf to expect an int-sized integer argument which was promoted from a short


For integer types, causes printf to expect a long-sized integer argument. For floating point types, this has no effect


For integer types, causes printf to expect a long long-sized integer argument


For floating point types, causes printf to expect a long double argument


For integer types, causes printf to expect a size_t-sized integer argument


For integer types, causes printf to expect a intmax_t-sized integer argument


For integer types, causes printf to expect a ptrdiff_t-sized integer argument

Specifier types

This is a list of standard specifiers for outputting the data to the stream. Column Supported gives an overview which specifiers are actually supported by the library.






Prints literal % character

d i


Prints signed int. No difference between either of them



Prints unsigned int

f F


Prints double in normal fixed-point notation. f and F only differs in how the strings for an infinite number or NaN are printed (inf, infinity and nan for f; INF, INFINITY and NAN for F).

e E


Prints double in standard form [-]d.ddd e[+-]ddd. e uses lower-case and E uses upper-case letter for exponent annotation.

g G


Prints double in either normal 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. Also, the decimal point is not included on whole numbers.

x X


Prints unsigned int as a hexadecimal number. x uses lower-case and X uses upper-case letters



Prints unsigned int in octal format



Prints null terminated string



Prints char type



Prints void * in an hex-based format. Reads input as unsigned int by default.

a A

Not yet

Prints double in hexadecimal notation. Currently it will print NaN when used



Prints nothing but writes the number of characters successfully written so far into an integer pointer parameter

Notes about float types

It is important to understand how library works under the hood to understand limitations on floating-point numbers. When it comes to level of precision, maximum number of digits is linked to support long or long long integer types.


When long long type is supported by the compiler (usually part of C99 or later), maximum number of valid digits is 18, or 9 digits if system supports only long data types.

If application tries to use more precision digits than maximum, remaining digits are automatically printed as all 0. As a consequence, output using LwPRINTF library may be different in comparison to other printf implementations.


Float data type supports up to 7 and double up to 15.

Additional specifier types

LwPRINTF implementation supports some specifiers that are usually not available in standard implementation. Those are more targeting embedded systems although they may be used in any general-purpose application



B b

Prints unsigned int data as binary representation.

K k

Prints unsigned char based data array as sequence of hex numbers. Use width field to specify length of input array. Use K for upper-case hex letters, k for lower-case.

Additional format specifiers
 1/* List of specifiers added in the library which are not available in standard printf implementation */
 3#include "lwprintf/lwprintf.h"
 6 * \brief           List of additional specifiers to print
 7 */
 9additional_format_specifiers(void) {
10    unsigned char my_array[] = { 0x01, 0x02, 0xA4, 0xB5, 0xC6 };
12    /* Binary output */
14    /* Prints number 8 in binary format, so "1000" */
15    lwprintf_printf("%b\r\n", 8U);
16    /* Prints number 16 in binary format with 10 places, so "     10000" */
17    lwprintf_printf("%10b\r\n", 16U);
18    /* Prints number 16 in binary format with 10 places, leading zeros, so "0000010000" */
19    lwprintf_printf("%010b\r\n", 16U);
21    /* Array outputs */
23    /* Fixed length with uppercase hex numbers, outputs "0102A4B5C6" */
24    lwprintf_printf("%5K\r\n", my_array);
25    /* Fixed length with lowercase hex numbers, outputs "0102a4b5c6" */
26    lwprintf_printf("%5k\r\n", my_array);
27    /* Variable length with uppercase letters, outputs "0102A4B5C6" */
28    lwprintf_printf("%*K\r\n", (int)LWPRINTF_ARRAYSIZE(my_array), my_array);
29    /* Variable length with lowercase letters, outputs "0102a4b5c6" */
30    lwprintf_printf("%*k\r\n", (int)LWPRINTF_ARRAYSIZE(my_array), my_array);
31    /* Variable length with uppercase letters and spaces, outputs "01 02 A4 B5 C6" */
32    lwprintf_printf("% *K\r\n", (int)LWPRINTF_ARRAYSIZE(my_array), my_array);
33    /* Variable length with uppercase letters and spaces, outputs "01 02 a4 b5 c6" */
34    lwprintf_printf("% *k\r\n", (int)LWPRINTF_ARRAYSIZE(my_array), my_array);