May the source be with you, but remember the KISS principle ;-)

Contents Bulletin Scripting in shell and Perl Network troubleshooting History Humor

sprintf in Perl

News Perl Language Recommended Links Reference Regular expressions  
sort substr Split sprintf  index and rindex tr
Pipes in Perl   History Humor Etc  

Function sprintf is not often considered to be string manipulation function in most Perl textbooks. It is usually studies along with printf function in the chapter devoted to I/O operation in Perl. But in reality it is important string manipulation function that overlaps with  substr , concatenate(dot), length and other string processing functions. It is indispensable when you need to assemble a string from one or several numeric values or mixture of numeric values (each using particular format) and strings.

Function sprintf accepts two arguments:

Format string

Format string was first introduced by Fortran and further developed in PL/1.  See printf format string - Wikipedia.

Here is the basic information about format string from sprintf man page. For more information see  sprintf() man page. Perl's sprintf() permits the following classic formal elements (called  specifiers in Perl-speak):

  1. c a character with the given number
  2. s a substring of the string or string justified in a certain manner. For example
  3. d a signed integer, in decimal
  4. u an unsigned integer, in decimal
  5. o an unsigned integer, in octal
  6. x an unsigned integer, in hexadecimal
  7. e a floating-point number, in scientific notation
  8. f a floating-point number, in fixed decimal notation
  9. g a floating-point number, in e or f notation

Perl also supports several additional useful specifiers:

  1. X like x, but using upper-case letters
  2. E like e, but using an upper-case "E"
  3. G like g, but with an upper-case "E" (if applicable)
  4. b an unsigned integer, in binary
  5. B like b, but using an upper-case "B" with the # flag
  6. p a pointer (outputs the Perl value's address in hexadecimal)
  7. n special: *stores* the number of characters output so far

Like C Perl permits the following flags between the %  and the specifiers letter:

  1. space -- prefix positive number with a space
  2. + -- prefix positive number with a plus sign
  3. - -- left-justify within the field
  4. 0 -- use zeros, not spaces, to right-justify
  5. # -- prefix non-zero octal with "0", non-zero hex with "0x"
  6. number -- minimum field width
  7. .number -- "precision": digits after decimal point for floating-point, max length for string, minimum length for integer
  8. l -- interpret integer as C type "long" or "unsigned long"
  9. h -- interpret integer as C type "short" or "unsigned short"

There is also one Perl-specific flag v (vector flag ):

This flag 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 strings with a separator (a dot .  by default). This can be useful for displaying ordinal values of characters in arbitrary strings:

  1. printf "%vd", "AB\x{100}"; # prints "65.66.256"
  2. printf "version is v%vd\n", $^V; # Perl's version

Put an asterisk *  before the v  to override the string to use to separate the numbers:

  1. printf "address is %*vX\n", ":", $addr; # IPv6 address
  2. printf "bits are %0*v8b\n", " ", $bits; # random bitstring

You can also explicitly specify the argument number to use for the join string using something like *2$v; for example:

  1. printf '%*4$vX %*4$vX %*4$vX', @addr[1..3], ":"; # 3

Perl also supports several macros and aliases to existing format items for backward compatibility. Among them:

Where a number would appear in the flags, an asterisk ("*'') may be used instead, in which case Perl uses the next item in the parameter list as the given number (that is, as the field width or precision). If a field width obtained through "*'' is negative, it has the same effect as the "-'' flag: left-justification.


Function sprintf is extremely convenient  if you want to assemble a formatted string from several numeric variables or mixture of string and numeric variable.

Specifying integer and real values

Often you need to render the number  with a certain number of places after the decimal point. For example two in case of dollar and cents. You can accomplish this using the "%.2d" format:

my $money = sprintf("%.2d", 5.9997);

This means rounding the value to two decimal points. Unless this is the way to perform calculation specified you are better off keeping numbers in memory with all of the available accuracy, rounding off only when you need to output it as a string.

Leading Zeros

If you need to put leading zeros you need to use %0nC specifier syntax lets you do just that, where 'n' is the field width, and C is the conversion specifier you want to use. A field width is the minimum (in this case) number of characters the value should fill. Any less than that, and the remainder is filled by prepending zeros to the value.

	sprintf("%03d", 642);		# outputs '00642'

The "%3d" specifier means a minimum width of three spaces, which, by default, will be right-justified. (Note: the alignment is not currently being displayed properly here.)

printf("%3d", 1); 1
printf("%03d", 1); 001
printf("%3d", -1); -1
printf("%03d", -1); -001
Left-justifying printf  output

String value are usually left-justifed. To archive that just add a minus sign (-) after the % symbol, like this:

printf("%-12s", $name); Nick

Here is a collection of printf examples for integer printing. Several different options are shown, including a minimum width specification, left-justified, zero-filled, and also a plus sign for positive numbers.

Description Code Result
At least five wide printf("'%5d'", 10); ' 10'
At least five-wide, left-justified printf("'%-5d'", 10); '10 '
At least five-wide, zero-filled printf("'%05d'", 10); '00010'
At least five-wide, with a plus sign printf("'%+5d'", 10); ' +10'
Five-wide, plus sign, left-justified printf("'%-+5d'", 10); '+10 '
A more complex example

Here is more complex example:

my $timestamp = sprintf( "%4d/%02d/%02d %2d:%02d:%02d",
                         $yr,$mon,$day, $h, $m, $s);

In that example, the variable $timestamp will be initialized with the value "2012/01/19 8:00:08".

Please note that the format string used a leading zero in  format components %02d that repeats several times. The leading zero means that is number has less digits then specified width, it will be filled from the left with leading zeroes as needed to make the number into the width specified (in this example two positions). 

Formatting IP addresses and large currency values

Often for large monetary value a special "money format" is needed. This format prints an integer with each three positions before decimal point marked with comma. In other words commas are used to distinguish dollars, thousand of dollars, millions of dollars. In Perl you can generate such a format  %v flag

This flag tells Perl to interpret the supplied string as a vector of integers, one for each format item in the format string. Perl applies the format to each part of the integer one by one, then joins the resulting strings with a separator (a dot .  by default). This can be useful for displaying ordinal values of characters in arbitrary strings:

  1. printf "version is v%vd\n", $^V; # Perl's version

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

  1. printf "address is %*vX\n", ":", $addr; # IPv6 address
  2. printf "bits are %0*v8b\n", " ", $bits; # random bitstring

You can also explicitly specify the argument number to use for the join string using something like *2$v; for example:

$ip=printf('%*4$vX %*4$vX %*4$vX', @addr, ":"); 

Top updates

Bulletin Latest Past week Past month
Google Search


Old News ;-)

[Jul 09, 2012] Formatting Output Using printf

This quote is from David Till book

If you want to write output that looks reasonable without going to all the trouble of using write and print formats, Perl provides a built-in function, printf, that prints formatted output.

If you are familiar with the C programming language, the behavior of printf in Perl will be familiar; the Perl printf and the C printf are basically the same

The arguments passed to the printf function are as follows:

When printf sees a field specifier, it substitutes the corresponding value in the printf argument list. The representation of the substituted value in the string depends on the field specifier that is supplied.

Field specifiers consist of the % character followed by a single character that represents the format to use when printing. Table 11.2 lists the field-specifier formats and the field-specifier character that represents each.

Table 11.2. Field specifiers for printf.
Single character
Integer in decimal (base-10) format
Floating-point number in scientific notation
Floating-point number in "normal" (fixed-point) notation
Floating-point number in compact format
Integer in octal (base-8) format
Character string
Unsigned integer
Integer in hexadecimal (base-16) format

Here is a simple example of a call to printf:

printf("The number I want to print is %d.\n", $number);

The string to be printed contains one field specifier, %d, which represents an integer. The value stored in $number is substituted for the field specifier and printed.

Field specifiers also support a variety of options, as follows:

If a floating-point number contains more digits than the field specifier wants, the number is rounded to the number of decimal places needed. For example, if 43.499 is being printed using the field %5.2f, the number actually printed is 43.50.

As with the write value field @##.##, printf might not always round up when it is handling numbers whose last decimal place is 5. This happens because some floating-point numbers cannot be stored exactly, and the nearest equivalent number that can be stored is a slightly smaller number (which rounds down, not up). For example, 43.495 when printed by %5.2f might print 43.49, depending on how 43.495 is stored.

You can use printf to print to other files. To do this, specify the file variable corresponding to the file to which you want to print, just as you would with print or write
printf MYFILE ("I am printing %d.\n", $value);
This means that changing the current default file using select affects printf.

Using (s)printf()

Jun 30, 2000 | PerlMonks

printf() and sprintf() work just like in C, with a few slight differences. printf() gives you a lot of control over the formatting of your values, which is what it was intended to do.

If you've ever wanted to make a nicely behaved, field-aligned report, round to an integer or specific decimal place, get octal or hexadecimal representations of your values, or just display your values in any other form imaginable, keep reading. printf() and sprintf() give you the utility to do that, and more.

printf() versus sprintf()

printf() and sprintf() look argumentally the same. That is, whatever arguments you pass to one, you can pass to the other without change. The difference is that printf() prints to a filehandle, and sprintf() returns the string printf() would have outputted.

To use printf() on a filehandle other than STDOUT, specify the filehandle you want to use just as you would with print, like so:

printf(HANDLE $format, @values);

The result will be printed to HANDLE.

sprintf doesn't take a filehandle, but instead returns the output into a string.

my $string = sprintf($format, @values);

The Format String

The format string in printf() is a number of tokens which describe how to print the variables you supply, and whatever else you want. Each variable format specifier starts with a %, is followed by zero or more of the optional modifiers, and ends with a conversion specifier.

A typical format string could look like this:

	"foo is %d"

Printed, it may look something like: 'foo is 12'. The %d is replaced by a variable specified after the format string argument. In this case, you would say:

	printf("foo is %d", $decimal);

so that %d is replaced with the value of $decimal. You can put as many specifiers in the format string as you like, with the same number of following arguments as there are specifiers. An example:

	printf("%d %s %f", $decimal, $string, $float);

Conversion Specifiers

You put these in your Format String. Each one, except %%, is replaced by the corresponding value in the printf argument list.

Others that simply exist for backward compatibility:

Format Specifiers

Each item below is optional (unless otherwise stated), and should be used in the order they appear here. If this is confusing, skip to the next section. It's intended as a reference, and copied from man 3 printf with some extra explanation and examples.

Leading Zeros

Say you have a number, something like 642, and you want to output it as 00642 instead. The %0nC specifier syntax lets you do just that, where 'n' is the field width, and C is the conversion specifier you want to use. A field width is the minimum (in this case) number of characters the value should fill. Any less than that, and the remainder is filled by prepending zeros on your value until it fits perfectly.

	printf("%05d", 642);		# outputs '00642'

You should note that certain conversions, like %f, are a little trickier. Floating point numbers (with %f) are always outputted with 6 places after the decimal point, unless you specify a precision with the '.' modifier (see below for a discussion of the '.' precision modifier). In other words, printing a value of '2' as %f will actually output as 2.000000. This means you have to take into account, when specifying the field width, that there are already 7 characters tacked on. To get the value of 2 to print with one leading zero, you have to use a field width of 9 (7 for the '.' and 6 zeros, 1 for the '2', and 1 for the leading zero).

All other specifiers act in this way, too. To find out how many characters are output by default for a specifier, output a value of 0 (zero) for it and count how many characters there are:

	# this outputs: '0, 0.000000, 0.000000e+00'
	printf("%d, %f, %e", 0, 0, 0);

You can also ask perl to count them for you:

	printf("There are %d characters\n", length(sprintf("%e", 0)));

Which should tell you there are 12 characters for 0 in scientific notation.

Padding with spaces

This is more or less the same as leading zeros, except it uses leading (or, if told, trailing) spaces to complete the field width. This is useful for lining up multiple lines of data into a report, for instance (though in that case, you may also want to specify a maximum field width to truncate long values - more on that below). The syntax is just like leading zeros, but drop the leading zero:

	printf("%6s", 'foo');		# prints '   foo'

By default, leading spaces are used, so values appear to be right-aligned in their field. To reverse this, put a '-' sign before the field width:

	printf("%-6s", 'foo');		# prints 'foo   '

For numeric values with default precision, like %f and %e, act here just like they do with leading zeros. %f, for example, won't have any padding unless you put a field width of more than 8.

Precision Modifier

The precision modifier tells printf() how many digits you want after the decimal point, if its a floating point specifier. If there are more digits than you specified, the value is rounded. If there are less, zeros are used to fill the space.

	printf("%.2f", 9.333333);		# prints '9.34'
	printf("%.2f", 9);			# prints '9.00'

For decimal values, the precision modifier has the same effect as the '0' modifier described above:

	printf("%.3f", 7);			# prints 007

For string values, it has the nice effect of specifying a maximum field width, where it will only print out the first n characters of the string. In combonation with the field width modifier described above, you can have a well-behaved-under-all-circumstances string field.

	printf("%.3s", 'foobar');		# prints 'foo'
	printf("%.10s", 'foobar');		# prints 'foobar'
	printf("%5.5s %5.5s", 'foobar', 'baz');	# prints 'fooba   baz'

Rounding Numbers with sprintf()

Ever wanted to round a floating point number to a decimal in perl? Or round it to an arbitrary decimal place? sprintf() gives you the ability to do that.

	# this sets $foo to '3'
	$foo = sprintf("%d", 3.14);

	# this sets $bar to '7.3531'
	$bar = sprintf("%.4f", 7.35309);

%d specifies to convert the given value to a decimal integer. The conversion rounds as necessary. %.4f specifies to convert the value given to a floating point number with a precision to 4 decimal places, rounding the value as needed.

Octal and Hexadecimal

You can convert your decimal based values to Hexadecimal and Octal values using printf() and sprintf(). To do so, specify the conversion as %o for octal, and %x for hexadecimal. %X is equivilant to %x, except the result is printed using capital letters.

	printf("%x", 15);	# prints 'f'
	printf("%X", 15);	# prints 'F'
	printf("%o", 15);	# prints '17'

As explained in the Format Modifiers section, using a '#' (pound sign) right after the % will convert the value to "alternate form." For %x and %X, it will prepend to the value '0x' and '0X' respectively. For %o, a single leading '0' (zero) is added. The extra characters using the # modifier are considered part of the field width.

	printf("%#x", 15);	# prints '0xf'
	printf("%#o", 15);	# prints '017'
	printf("%#4x", 15);	# prints ' 0xf'

In the last example, the field width of 4 is specified. Since the # modifier adds two extra characters to the value, it ends up taking 3 characters in total. Thus the single leading space.

Formatting Data with sprintf (Learning Perl, 3rd Edition)

Formatting Data with sprintf

The sprintf function takes the same arguments as printf (except for the optional filehandle, of course), but it returns the requested string instead of printing it. This is handy if you want to store a formatted string into a variable for later use, or if you want more control over the result than printf alone would provide:

my $date_tag = sprintf
  "%4d/%02d/%02d %2d:%02d:%02d",
  $yr, $mo, $da, $h, $m, $s;

In that example, $date_tag gets something like "2038/01/19 3:00:08". The format string (the first argument to sprintf) used a leading zero on some of the format number, which we didn't mention when we talked about printf formats in Chapter 6, "I/O Basics". The leading zero on the format number means to use leading zeroes as needed to make the number as wide as requested. Without a leading zero in the formats, the resulting date-and-time string would have unwanted leading spaces instead of zeroes, looking like "2038/ 1/19 3: 0: 8".

15.3.1. Using sprintf with "Money Numbers"

>One popular use for sprintf is when a number needs to be rendered with a certain number of places after the decimal point, such as when an amount of money needs to be shown as 2.50 and not 2.5 -- and certainly not as 2.49997! That's easy to accomplish with the "%.2f" format:

my $money = sprintf "%.2f", 2.49997;

The full implications of rounding are numerous and subtle, but in most cases you should keep numbers in memory with all of the available accuracy, rounding off only for output.

If you have a "money number" that may be large enough to need commas to show its size, you might find it handy to use a subroutine like this one.[337]

[337]Yes, we know that not everywhere in the world are commas used to separate groups of digits, not everywhere are the digits grouped by threes, and not everywhere the currency symbol appears as it does for U.S. dollars. But this is a good example anyway, so there!

sub big_money {
  my $number = sprintf "%.2f", shift @_;
  # Add one comma each time through the do-nothing loop
  1 while $number =~ s/^(-?\d+)(\d\d\d)/$1,$2/;
  # Put the dollar sign in the right place
  $number =~ s/^(-?)/$1\$/;

This subroutine uses some techniques you haven't seen yet, but they logically follow from what we've shown you. The first line of the subroutine formats the first (and only) parameter to have exactly two digits after the decimal point. That is, if the parameter were the number 12345678.9, now our $number is the string "12345678.90".

The next line of code uses a while modifier. As we mentioned when we covered that modifier in Chapter 10, "More Control Structures", that can always be rewritten as a traditional while loop:

while ($number =~ s/^(-?\d+)(\d\d\d)/$1,$2/) {

What does that say to do? It says that, as long as the substitution returns a true value (signifying success), the loop body should run. But the loop body does nothing! That's okay with Perl, but it tells us that the purpose of that statement is to do the conditional expression (the substitution), rather than the useless loop body. The value 1 is traditionally used as this kind of a placeholder, although any other value would be equally useful.[338] This works just as well as the loop above:

[338]Which is to say, useless. By the way, in case you're wondering, Perl optimizes away the constant expression so it doesn't even take up any runtime.

'keep looping' while $number =~ s/^(-?\d+)(\d\d\d)/$1,$2/;

So, now we know that the substitution is the real purpose of the loop. But what is the substitution doing? Remember that $number will be some string like "12345678.90" at this point. The pattern will match the first part of the string, but it can't get past the decimal point. (Do you see why it can't?) Memory $1 will get "12345", and $2 will get "678", so the substitution will make $number into "12345,678.90" (remember, it couldn't match the decimal point, so the last part of the string is left untouched).

Do you see what the dash is doing near the start of that pattern? (Hint: The dash is allowed at only one place in the string.) We'll tell you at the end of this section, in case you haven't figured it out.

We're not done with that substitution statement yet. Since the substitution succeeded, the do-nothing loop goes back to try again. This time, the pattern can't match anything from the comma onward, so $number becomes "12,345,678.90". The substitution thus adds a comma to the number each time through the loop.

Speaking of the loop, it's still not done. Since the previous substitution was a success, we're back around the loop to try again. But this time, the pattern can't match at all, since it has to match at least four digits at the start of the string, so now that is the end of the loop.

Why couldn't we have simply used the /g modifier to do a "global" search-and-replace, to save the trouble and confusion of the 1 while? We couldn't use that because we're working backwards from the decimal point, rather than forward from the start of the string. Putting the commas in a number like this can't be done simply with the s///g substitution alone.[339]

[339]At least, it can't be done without some more-advanced regular expression techniques than we've shown you so far. Those darn Perl developers keep making it harder and harder to write Perl books that use the word "can't."

So, did you figure out the dash? It's allowing for a possible minus-sign at the start of the string. The next line of code makes the same allowance, putting the dollar-sign in the right place so that $number is something like "$12,345,678.90", or perhaps "-$12,345,678.90" if it's negative. Note that the dollar sign isn't necessarily the first character in the string, or that line would be a lot simpler. Finally, the last line of code returns our nicely formatted "money number," ready to be printed in the annual

Recommended Links

Softpanorama Top Visited

Softpanorama Recommended

sprintf -

printf format string - Wikipedia, the free encyclopedia

Using (s)printf()

sprintf in Perl description



Groupthink : Understanding Micromanagers and Control Freaks : Toxic Managers : BureaucraciesHarvard Mafia : Diplomatic Communication : Surviving a Bad Performance Review : Insufficient Retirement Funds as Immanent Problem of Neoliberal Regime : PseudoScience : Who Rules America : Two Party System as Polyarchy : Neoliberalism  : The Iron Law of Oligarchy : Libertarian Philosophy


Skeptical Finance : John Kenneth Galbraith : Keynes : George Carlin : Skeptics : Propaganda  : SE quotes : Language Design and Programming Quotes : Random IT-related quotes : Oscar Wilde : Talleyrand : Somerset Maugham : War and Peace : Marcus Aurelius : Eric Hoffer : Kurt Vonnegut : Otto Von Bismarck : Winston Churchill : Napoleon Bonaparte : Ambrose Bierce : Oscar Wilde : Bernard Shaw : Mark Twain Quotes


Vol 26, No.1 (January, 2013) Object-Oriented Cult : Vol 25, No.12 (December, 2013) Rational Fools vs. Efficient Crooks: The efficient markets hypothesis : Vol 25, No.08 (August, 2013) Cloud providers as intelligence collection hubs : Vol 23, No.10 (October, 2011) An observation about corporate security departments : Vol 23, No.11 (November, 2011) Softpanorama classification of sysadmin horror stories : Vol 25, No.05 (May, 2013) Corporate bullshit as a communication method : Vol 25, No.10 (October, 2013) Cryptolocker Trojan (Win32/Crilock.A) : Vol 25, No.06 (June, 2013) A Note on the Relationship of Brooks Law and Conway Law


Fifty glorious years (1950-2000): the triumph of the US computer engineering : Donald Knuth : TAoCP and its Influence of Computer Science : Richard Stallman : Linus Torvalds  : Larry Wall  : John K. Ousterhout : CTSS : Multix OS Unix History : Unix shell history : VI editor : History of pipes concept : Solaris : MS DOSProgramming Languages History : PL/1 : Simula 67 : C : History of GCC developmentScripting Languages : Perl history   : OS History : Mail : DNS : SSH : CPU Instruction Sets : SPARC systems 1987-2006 : Norton Commander : Norton Utilities : Norton Ghost : Frontpage history : Malware Defense History : GNU Screen : OSS early history

Classic books:

The Peter Principle : Parkinson Law : 1984 : The Mythical Man-MonthHow to Solve It by George Polya : The Art of Computer Programming : The Elements of Programming Style : The Unix Haterís Handbook : The Jargon file : The True Believer : Programming Pearls : The Good Soldier Svejk : The Power Elite

Most popular humor pages:

Manifest of the Softpanorama IT Slacker Society : Ten Commandments of the IT Slackers Society : Computer Humor Collection : BSD Logo Story : The Cuckoo's Egg : IT Slang : C++ Humor : ARE YOU A BBS ADDICT? : The Perl Purity Test : Object oriented programmers of all nations : Financial Humor : Financial Humor Bulletin, 2008 : Financial Humor Bulletin, 2010 : The Most Comprehensive Collection of Editor-related Humor : Programming Language Humor : Goldman Sachs related humor : Greenspan humor : C Humor : Scripting Humor : Real Programmers Humor : Web Humor : GPL-related Humor : OFM Humor : Politically Incorrect Humor : IDS Humor : "Linux Sucks" Humor : Russian Musical Humor : Best Russian Programmer Humor : Microsoft plans to buy Catholic Church : Richard Stallman Related Humor : Admin Humor : Perl-related Humor : Linus Torvalds Related humor : PseudoScience Related Humor : Networking Humor : Shell Humor : Financial Humor Bulletin, 2011 : Financial Humor Bulletin, 2012 : Financial Humor Bulletin, 2013 : Java Humor : Software Engineering Humor : Sun Solaris Related Humor : Education Humor : IBM Humor : Assembler-related Humor : VIM Humor : Computer Viruses Humor : Bright tomorrow is rescheduled to a day after tomorrow : Classic Computer Humor


The Last but not Least

Copyright © 1996-2014 by Dr. Nikolai Bezroukov. was created as a service to the UN Sustainable Development Networking Programme (SDNP) in the author free time. This document is an industrial compilation designed and created exclusively for educational use and is distributed under the Softpanorama Content License. Site uses AdSense so you need to be aware of Google privacy policy. Original materials copyright belong to respective owners. Quotes are made for educational purposes only in compliance with the fair use doctrine. This is a Spartan WHYFF (We Help You For Free) site written by people for whom English is not a native language. Grammar and spelling errors should be expected. The site contain some broken links as it develops like a living tree...

You can use PayPal to make a contribution, supporting hosting of this site with different providers to distribute and speed up access. Currently there are two functional mirrors: (the fastest) and


The statements, views and opinions presented on this web page are those of the author and are not endorsed by, nor do they necessarily reflect, the opinions of the author present and former employers, SDNP or any other organization the author may be associated with. We do not warrant the correctness of the information provided or its fitness for any purpose.

Last modified: February, 19, 2014