Perl sprintf Function

The sprintf function emulates the C sprintf function.

The sprintf function returns a string formatted by the usual printf conventions of the C library function sprintf. Instead of the printf function which prints the string to the current output filehandle or to the one specified by a filehandle, the sprintf function will return the formatted string in a scalar variable.

The syntax form of the sprintf function is as follows:

$stringsprintf FORMAT, LIST

where the FORMAT is used to return a formatted string based on the LIST values.

The Perl sprintf function FORMAT allows you to use the following conversions:

 

Symbol

Meaning

%%

a percent sign

%c

a character with the given number

my $string = sprintf '%c', 0x61;
print "$string\n";  # it displays: a

%s

a string

my $string = sprintf '%s', "abcd";
print "$string\n";  # it displays: abcd

%d

a signed integer, in decimal

my $string = sprintf '%d', 123415;
print "$string\n";  # it displays: 123415

%D

a synonym for %ld

my $string = sprintf '%ld', 234151345;
print "$string\n";  # it displays: 234151345

%i

a synonym for %d

my $string = sprintf '%i', -17324;
print "$string\n";  # it displays: -17324

%u

an unsigned integer, in decimal

my $string = sprintf '%u', 2217324;
print "$string\n";  # it displays: 2217324

%U

a synonym for %lu

my $string = sprintf '%U', 2217324334;
print "$string\n";  # it displays: 2217324334

%o

an unsigned integer, in octal

my $string = sprintf '%o', 934522;
print "$string\n";  # it displays: 3441172

%O

a synonym for %lo

%x

an unsigned integer, in hexadecimal

my $string = sprintf '%x', 934522;
print "$string\n";  # it displays: e427a

%X

like %x, but using uppercase letters

my $string = sprintf '%X', 934522;
print "$string\n";  # it displays: E427A

%e

a floating-point number in scientific notation 

my $string = sprintf '%e', -12.345;
print "$string\n";  # it displays: -1.234500e+001

%E

like %e, but using uppercase "E" 

my $string = sprintf '%E', -12.345;
print "$string\n";  # it displays: -1.234500E+001

%f

a floating-point number in fixed decimal notation

my $string = sprintf '%f', -12.345;
print "$string\n";  # it displays: -12.345000

%F

a synonym for %f

my $string = sprintf '%F', -12.345;
print "$string\n";  # it displays: -12.345000

%g

a floating-point number in %e or %f notation

my $string = sprintf '%g', -1.234500E+1;
print "$string\n";  # it displays: -12.345

%G

like %g, but with an uppercase "E", if applicable 

%b

an unsigned integer, in binary 

my $string = sprintf '%b', 123;
print "$string\n";  # it displays: 1111011

%B

like %b, but using an uppercase "E", with the # flag

%p

a pointer (outputs the Perl value’s address in hexadecimal)

%n

special: *stores* the number of characters output so far into the next variable in the parameter list


You may specify several additional attributes between the % and the format letter in order to control the interpretation of the format:

 

Attribute

Meaning

format

parameter

index

By default sprintf will format the next unused argument in the list, but this parameter index, such as 2$, enables you to take the arguments out of order.

my $string = sprintf '%2$d %1$d', 12, 34;
print "$string\n";  # it displays: 34 12
 
$string = sprintf '%3$d %d %1$d', 1, 2, 3;
print "$string\n";  # it displays: 3 1 1

flags one or more of:

space

+

-

0

#

prefix non-negative number with a space

prefix non-negative number with a plus sign

left-justify within the field

use zeros, not spaces, to right-justify

ensure the leading "0" for any octal,

prefix non-zero hexadecimal with "0x" or "0X",

prefix non-zero binary with "0b" or "0B"

vector flag

It tells Perl to interpret the supplied string as a vector of integers, one for each character in the string.

Perl applies the format to each integer in turn, then joins the resulting string with a separator (a dot . by default).

If you put an asterisk * before the v you can override the string to use to separate the numbers:

my $string = sprintf "%*vd", ":", "AB\x{100}"; 
print "$string\n";  # it displays 65:66:256

(min) width

Arguments are usually formatted to be as wide as required to display the given value, but you can override the width by putting a number here, or get the width from the next argument (with *):

my $string = sprintf "%5s", "a"; 
print "$string\n";  # it displays "    a"
 
$string = sprintf "%*s", 5, "a";
print "$string\n";  # it displays "    a"

precision, or max width

You can specify a precision (for numeric conversions) or a maximum width (for string conversions) by specifying a . followed by a number.

For floating-point formats (excepting g or G) this specifies how many places right of the decimal point to show:

my $string = sprintf "%.2f", 123.4567; 
print "$string\n";  # it displays: 123.46
 
$string = sprintf "%.5s", "language";  
print "$string\n";  # it displays: langu

size

For numeric conversions, you can specify the size to interpret the number as using l, h, V, q, L or ll.

So:

l - interpret integer as C type "long" or "unsigned long"

h - interpret integer as C type "short" or "unsigned short" or quads (typically 64-bit integers)

qL or ll  - interpret integer as C type "long long", "unsigned long long" or "quads" (typically 64-bit integers)

order of args

You can use * to require additional arguments, these are consumed from the argument list in the order they appear in the format specification before the value to format:

my $val = 1234.12345;
my $string = sprintf "%*.*s", 9, 7, $val;
print "$string\n";  # it displays: "  1234.12"

In the above example, 9 is uses for the width, 7 for the precision, and $val as the value to format.

Both Perl sprintf and printf functions allow you to display your values in whatever formatted report you want, including conversion between decimal, octal or hexadecimal, aligned fields, rounding numbers and so on.

Basically, they have the same arguments and the difference between these two functions is that printf prints the formatted list of arguments to a filehandle, and sprintf returns the formatted list into a string.

So, for the printf function you have the following syntax form:

printf (HANDLE $format, LIST);

and the result will be printed to HANDLE.

The sprintf function has the following syntax form:

my $string = sprintf($format, LIST);
and the result will be returned in the $string variable.

Your computer represents the floating-point numbers in binary and it cannot store all numbers exactly. For example, if you have some arithmetical operations to do, the result number could lose precision.

In many situations, you don’t need to use all that long decimals, a few from them are sufficient.

To limit the number of your decimals, you can use the Perl sprintf built-in function. See the following example:

#!/usr/local/bin/perl
 
use strict;
use warnings;
 
my $string = 4 / 3; 
print "$string\n";  # it prints 1.33333333333333
 
# you don't need all that decimals
 
$string = sprintf "%.2f", 4 / 3;
print "$string\n";  # it prints 1.33

You can use the sprintf function to round a certain number of decimals of the floating-point numbers, by using the f conversion format:

#!/usr/local/bin/perl
 
use strict;
use warnings;
 
#!/usr/local/bin/perl
 
use strict;
use warnings;
 
my $string = sprintf "%.3f %.2f", 12.343789, -12.567;
print "$string\n";  # it prints: 12.344 -12.57
 
$string = sprintf "%.3f", 12.3;
print "$string\n";  # it prints: 12.300
Here . followed by a number is the precision modifier and tells sprintf how many digits you want after the decimal point.

If there are more digits than you specified, the value is rounded – see the first usage of sprintf from the above example.

If there are less digits, zeros are used to fill the space – see the second usage of sprintf from above.

There are many ways to perform such a conversion and the use of the Perl sprintf function is one of the easiest. You can use it either with x or X format character:

#!/usr/local/bin/perl
 
use strict;
use warnings;
 
my $hex = sprintf("%x", 12345678);     # lower case a-f
print "$hex\n";  # it prints: bc614e
 
$hex = sprintf("%X", 12345678);        # upper case A-F
print "$hex\n";  # it prints: BC614E
 

There are many ways to perform such a conversion and the use of the sprintf function is one of the easiest. You can use it with the o format character:

#!/usr/local/bin/perl
 
use strict;
use warnings;
 
my $oct = sprintf("%o", 12345678);    
print "$oct\n";  # it prints: 57060516

You can use the sprintf function with the b format character:

#!/usr/local/bin/perl
 
use strict;
use warnings;
 
my $bin = sprintf("%b", 12345678);
print "$bin\n";  # it prints: 101111000110000101001110

The sprintf function can be used in a very convenient way to pad a string on the left or right with blanks.

The following example shows you how to pad a string with blanks on the left side:

#!/usr/local/bin/perl
 
use strict;
use warnings;
 
my $pad_len = 15;
my $text = "1234567890";
 
my $padded = sprintf("'%${pad_len}s'", $text);
print "$padded\n";  # it prints: '     1234567890'
 
# the same thing
$padded = sprintf("'%*s'", $pad_len, $text);
print "$padded\n";  # it prints: '     1234567890'
The $pad_len is the length to which you wish to pad the string, $text contains the string to padded and $padded the resulting string.

Please note that in the first use of the sprintf function instead of $pad_len was used ${pad_len}.

Anytime when in an interpolation (inside double quotes) a scalar variable is followed by a character that has some special meaning to Perl (in our case the s character) you need to wrap the name of the scalar in curly braces to make it clear to Perl what you want.

The Perl sprintf function doesn’t truncate the value to convert, if in our example the value of the $pad_len scalar variable is less than 10 (the length of the $text variable) the value of the $padded variable will be "1234567890".

The following example shows you the same thing, but padding a string with blanks on the right side:

#!/usr/local/bin/perl
 
use strict;
use warnings;
 
my $pad_len = 15;
my $text = "1234567890";
 
my $padded = sprintf("'%-${pad_len}s'", $text);
 
print "$padded\n";  # it prints: '1234567890    
 
# the same thing
$padded = sprintf("'%-*s'", $pad_len, $text);
 
print "$padded\n";  # it prints: '1234567890 
Padding with blanks is very useful for lining up multiple lines of data into a report.

The sprintf function can be used in a very convenient way to pad a number on the left with zeros.

The following example shows you how to pad a number with zeros on the left side:

#!/usr/local/bin/perl
 
use strict;
use warnings;
 
my $pad_len = 10;
my $num = 12345;
 
my $padded = sprintf("'%0${pad_len}d'", $num);
 
print "$padded\n";  # it prints: '0000012345'
 
# the same thing
$pad_len = 4;
$padded = sprintf("'%0*d'", $pad_len, $num);
 
print "$padded\n";  # it prints: '12345'
The $pad_len is the length to which you wish to pad the number, $num contains the number to padded and $padded the resulting string.

Please note that in the first use of the sprintf function instead of $pad_len was used ${pad_len}.

Anytime when in an interpolation (inside double quotes) a scalar variable is followed by a character that has some special meaning to Perl (in our case the s character) you need to wrap the name of the scalar in curly braces to make it clear to Perl what you want.

The Perl sprintf function doesn’t truncate the value to convert. In the second example, the value of $pad_len scalar variable is 4 (less than the length of $num), but $padded still contains all the digits of the number, i.e the number is not truncated during the conversion.

Regarding the floating-point numbers, these are always outputted with 6 places after the decimal point, unless you specify a precision with the . precision modifier.

So, when you specify the field length you have to take into account that there are already 7 characters used. To get the value of a number with one or more leading zeroes, you need to use a length greater than 8.

See the next code snippet for an example:

#!/usr/local/bin/perl
 
use strict;
use warnings;
 
my $string = sprintf "%f", 1;
 
print "$string\n";  # it prints: 1.000000
 
$string = sprintf "%09f", 1;
 
print "$string\n";  # it prints: 01.000000
 

You can very easy to expand the variable’s value in a text string by using the sprintf function and double quotes for interpolation.

See the following example:

#!/usr/local/bin/perl
 
use strict;
use warnings;
 
my $s = 'split';
my $j = 'join';
my $string = sprintf "You can use %s and %s to do this.", $s, $j;
 
print "$string\n"; 
# it prints: You can use split and join to do this.
The $s and $j variables will be expanded with their values in the string returned by the sprintf function.

You can use the sprintf function to format floating-point numbers. In the following code snippet are provided a several commented examples that show you how to control field widths, printing left or right justified, and zero-filled.

#!/usr/local/bin/perl
 
use strict;
use warnings;
 
my $string = sprintf "'%5.2f'", 1234.734;
print "$string\n"; 
# it prints: '1234.73'
# 5 for length, 2 decimal digits, as you can see from
# the output, the floating-point number is not truncated
 
$string = sprintf "'%10.2f'", 1234.734;
print "$string\n";  
# it prints: '   1234.73'
# 10 for length, 2 decimal digits, the floating-point number
# is left padding with blanks (right-justified)
 
$string = sprintf "'%010.2f'", 1234.734;
print "$string\n"; 
# it prints: '0001234.73'
# 10 for length, 2 decimal digits, the floating-point number
# is left padding with zeroes
 
$string = sprintf "'%-10.2f'", 1234.734;
print "$string\n"; 
# it prints: '1234.73   '
# 10 for length, 2 decimal digits, the floating-point number
# is right padding with blanks (left-justified)

You can use the Perl sprintf function to get the local time of your computer in an appropriate format, returning the result in a string variable.

See the following code snippet:

#!/usr/local/bin/perl
 
use strict;
use warnings;
 
my $time = localtime(time);
my ($sec, $min, $hour, $mday, $mon, $year,
    $wday, $yday, $isdst) = localtime(time);
 
my $formatedTime = sprintf "%4d-%02d-%02d %02d:%02d:%02d",
                $year+1900, $mon+1, $mday, $hour, $min, $sec;
print "$formatedTime\n";
# sample of printing: 2010-06-26 16:55:50
You can use whatever separators to delimitate the data time fields.

You can easily use the sprintf function in the context of regular expressions. The special variables like $1, $2, $3, … or $`, $', $& set by the regular expressions engine can be used with the sprintf function.

The following example shows you how to replace notations like 4/25/10 (where the month appears first) by the conformant notation 2010-25-04 recommended by ISO 8601.

See the code:

#!/usr/local/bin/perl
 
use strict;
use warnings;
 
my $date = '4/25/10';
$date =~ m/(\d{1,2})\/(\d{1,2})\/(\d{2,4})/;
print "$1, $2, $3\n";
# it prints: 4, 25, 10
 
my $year = $3 < 50 ? 2000+$3 : 1900+$3;
$date = sprintf "%04d-%02d-%02d", $year, $1, $2;
print "$date\n";
# it prints: 2010-04-25
I used the conditional operator to modify the year and I assumed that if the input year is less than 50, the output year is greater than 2000. I printed also the values of the special variables $1, $2 and $3 set by the regex match operator.

Or you can use the /e modifier of the substitution operator s/// to run the Perl sprintf function inside the regular expression as pure Perl code, as you can see in the following short example:

#!/usr/local/bin/perl
 
use strict;
use warnings;
 
my $floats = '12.4573, 121.8967, -34.234';
$floats =~ s/(-?[0-9]+\.[0-9]*)/sprintf "%.2f", $1/eg;
 
print "$floats\n";
# it prints: 12.46, 121.90, -34.23

The expression -?[0-9]+\.[0-9]* is used to match a floating-point number and by wrapping it by round parentheses allows us to store the floating-point number in the $1 variable.

The values stored in $floats will be formatted by the sprintf function. The /g modifier of the substitution operator allows us to match all the floating-point numbers contained in the $floats variable.