SCALARs and strings

sprintf#

Build a formatted string from a format template and a list of values.

sprintf takes a FORMAT string containing literal text interspersed with %-introduced conversion specifiers, consumes values from LIST to fill each specifier, and returns the resulting string. It is the same machinery that drives printf, minus the write to a filehandle. Perl implements its own formatter; it does not call the C library’s sprintf(3) except for the final floating-point digit generation, so non-standard extensions that happen to exist in your libc are not available here.

Synopsis#

my $s = sprintf $format, @args;
my $s = sprintf "%-10s %5d", $name, $count;
my $s = sprintf "%.3f", $x;

What you get back#

A single scalar string. Never a list, regardless of context. If FORMAT contains no % specifiers, the return value is FORMAT unchanged and LIST is ignored. If FORMAT references more arguments than LIST supplies, the missing values are treated as undef (numeric zero or the empty string depending on the conversion), and a Missing argument in sprintf warning is issued under use warnings.

Passing an array as the first argument is almost always a mistake — the array is evaluated in scalar context, so Perl uses its element count as the format. Use sprintf $format, @rest with the format held separately, or sprintf "@array" for the array-as-string case.

Global state it touches#

  • LC_NUMERIC locale, when use locale is in effect and POSIX::setlocale has been called, determines the decimal-point character used by %e, %f, %g and their upper-case variants. Without use locale the decimal point is always ., even if the process locale says otherwise.

  • No other special variables are consulted. sprintf does not read $_; an explicit list is required.

Conversion specifiers#

The core set, in the order you will actually reach for:

Spec

Meaning

%s

String. Stringifies the argument.

%d, %i

Signed integer in decimal. Floats are truncated toward zero.

%u

Unsigned integer in decimal.

%f, %F

Fixed-point floating point. Default 6 digits after the decimal.

%e, %E

Scientific notation. Upper-case E selects the upper-case form.

%g, %G

%e or %f, whichever is shorter. Precision is significant digits, not digits after the decimal.

%x, %X

Unsigned integer in hexadecimal; %X uses upper-case AF.

%o

Unsigned integer in octal.

%b, %B

Unsigned integer in binary.

%c

Single character whose codepoint is the given integer.

%%

A literal %. Consumes no argument.

%p

Perl-value address, in hexadecimal. Diagnostic use only.

%n

Stores the number of characters written so far into the next argument (which must be a writable scalar).

%a, %A

Hexadecimal floating point.

Upper-case size synonyms %D %U %O and %F exist for historical compatibility; prefer the lower-case forms.

Flags, width, precision#

Between % and the conversion letter, in order:

  1. Argument indexN$ picks the N-th argument (1-based): sprintf '%2$s %1$s', 'world', 'hello' yields "hello world".

  2. Flags — any combination of:

    • - left-justify within the field (default is right-justify).

    • + prefix non-negative numbers with +.

    • ` ` (a space) prefix non-negative numbers with a space. When both space and + are given, + wins.

    • 0 pad numeric conversions with zeros instead of spaces. Ignored when - is also set or a precision is given for integers.

    • # alternate form: 0 prefix for octal, 0x/0X prefix for non-zero hex, 0b/0B prefix for non-zero binary.

  3. Minimum width — a decimal number, or * to take the width from the next argument, or *N$ for an explicit argument. Negative width (via *) is equivalent to the - flag.

  4. Precision. followed by a decimal number, or .* (next argument), or .*N$. Meaning depends on the conversion:

    • %f / %e: digits after the decimal point (default 6).

    • %g: total significant digits.

    • %d / %x / %o / %b: minimum digits; the number is zero-padded to this width. The 0 flag is ignored when a precision is present for integers.

    • %s: maximum width; truncates.

  5. Size modifierhh, h, j, l, q, L, ll, t, z, V. Interprets the argument as a specific C type. Almost never useful from Perl — Perl has one integer type and one float type, and Perl-level values do not overflow into the sizes these modifiers select. V is a no-op meaning “Perl’s default size”.

  6. Conversion letter — one of the table entries above.

The vector flag#

Prefix the conversion letter with v (optionally *v or *N$v to supply a separator) and Perl treats the argument as a vector of codepoints, applying the conversion to each codepoint and joining the results with . (or the supplied separator):

sprintf "%vd", "AB\x{100}";            # "65.66.256"
sprintf "%vX", "\x01\x02\x1f";         # "1.2.1F"
sprintf "%*vX", ":", "\xde\xad\xbe\xef"; # "DE:AD:BE:EF"

Common uses: rendering $^V, formatting IPv4 / IPv6 byte sequences, or dumping bitstrings. The argument is always read as a string of codepoints, not as a list.

Examples#

Pad and align strings in a fixed-width report column:

printf "%-10s %5d\n", "widgets", 42;   # "widgets        42\n"
printf "%-10s %5d\n", "sprockets", 7;  # "sprockets       7\n"

Zero-pad a fixed-width integer, e.g. for lexicographic sort keys or line numbers:

sprintf "%08d", 1234;                  # "00001234"
sprintf "%05d", -7;                    # "-0007"  (sign consumes a slot)

Round to a fixed number of decimal places. sprintf does the rounding; printf is a common way to coerce a display value:

sprintf "%.3f", 3.14159265;            # "3.142"
sprintf "%.0f", 2.5;                   # "2" or "3" — banker's rounding
                                       # is platform-dependent

Scientific notation, with and without a chosen precision:

sprintf "%e",    6.022e23;             # "6.022000e+23"
sprintf "%.2e",  6.022e23;             # "6.02e+23"
sprintf "%g",    0.0001234;            # "0.0001234"
sprintf "%g",    0.00001234;           # "1.234e-05"  (switches to %e)

Hex, octal, and binary with the # alternate-form prefix:

sprintf "%#x",  255;                   # "0xff"
sprintf "%#o",  8;                     # "010"
sprintf "%#b",  10;                    # "0b1010"
sprintf "%08b", 10;                    # "00001010"   (no prefix, width 8)

Character from a codepoint — %c is essentially chr routed through the format engine:

sprintf "%c", 65;                      # "A"
sprintf "%c", 0x2014;                  # "—"  (em dash)

Field width from the argument list — useful when the width is computed at runtime:

my $w = 12;
sprintf "%-*s|", "name", $w;           # "name        |"

Out-of-order arguments — useful when the same value appears multiple times or when localised formats reorder placeholders:

sprintf "%2\$s loves %1\$s", "Alice", "Bob";   # "Bob loves Alice"

Build an IPv4 address string:

sprintf "%vd", "\x7f\x00\x00\x01";     # "127.0.0.1"

Capture length via %n (the receiving argument must be a writable scalar):

my $written;
my $s = sprintf "hello%n, world", $written;
# $s       is "hello, world"
# $written is 5

Edge cases#

  • Integer truncation on %d with floats: %d converts via integer coercion, which truncates toward zero. sprintf "%d", 3.9 is "3", not "4". Use %.0f if you want banker’s-rounded display, or int / sprintf "%.0f" explicitly first.

  • %s on an object: stringification runs, which may invoke overloaded "" or fall back to "ClassName=HASH(0x…)". There is no way to suppress overloading inside sprintf; call overload::StrVal($obj) first if you need the raw form.

  • Missing arguments: sprintf "%s %s", "one" returns "one " and warns Missing argument in sprintf at under use warnings. No exception is raised.

  • Too many arguments: extras are ignored silently. No warning.

  • %s with precision truncates, %d with precision zero-pads. sprintf "%.3s", "abcdef" is "abc". sprintf "%.3d", 7 is "007".

  • %0 flag vs precision on integers: precision wins. sprintf "%05.3d", 7 is "  007", not "00007" — the 0 flag is ignored once you give an explicit integer precision.

  • Negative width via *: sprintf "%*s", -6, "x" is "x     ". Negative precision via .* counts as no precision at all.

  • NaN and Inf: sprintf "%f", 9**9**9 yields "Inf"; sprintf "%f", -sin(9**9**9) yields "NaN". Exact spelling ("Inf" vs "inf", "NaN" vs "nan") follows the Perl build’s convention, not the %f / %F case distinction.

  • Locale decimal point: with use locale and a de_DE locale, sprintf "%.2f", 1.5 can produce "1,50". Without use locale the result is always "1.50". Code that writes numeric output for consumption by other programs should either avoid use locale in that scope or use use locale ':not_characters' and format numbers outside locale influence.

  • %p is diagnostic-only: the hexadecimal pointer value changes from run to run and is meaningless outside the running process. Do not use it as an identity key — two references may share the same address after the first has been freed.

  • Array passed as FORMAT: sprintf @a formats using the scalar count of @a as the format string. Almost always a bug. Always keep the format in its own scalar.

  • Unsupported size modifier: on platforms lacking e.g. long doubles, the L/q/ll size on a float conversion silently falls back to the default size, and a printf warning is issued under use warnings. To promote this to an exception, use use warnings FATAL => 'printf'.

Differences from upstream#

Fully compatible with upstream Perl 5.42.

See also#

  • printf — same formatting engine, but writes to a filehandle instead of returning the string

  • print — use with a pre-built sprintf result when you want to format once and write to several handles

  • chr — single codepoint to single character; equivalent to sprintf "%c", $n

  • hex, oct — inverse operations: parse a string in hex/octal/binary back into a number

  • pack — build a binary string from a template; reach for it when the output is bytes, not a human-readable format

  • $_not consulted by sprintf; unlike many built-ins it always needs an explicit list