sprintf

Description

Parameters

format

The format string is composed of zero or more directives:
ordinary characters (excluding %) that are
copied directly to the result and conversion
specifications, each of which results in fetching its
own parameter. This applies to both sprintf()
and printf().

Each conversion specification consists of a percent sign
(%), followed by one or more of these
elements, in order:

An optional sign specifier that forces a sign
(- or +) to be used on a number. By default, only the - sign is used
on a number if it's negative. This specifier forces positive numbers
to have the + sign attached as well.

An optional padding specifier that says
what character will be used for padding the results to the
right string size. This may be a space character or a
0 (zero character). The default is to pad
with spaces. An alternate padding character can be specified
by prefixing it with a single quote (').
See the examples below.

An optional alignment specifier that says
if the result should be left-justified or right-justified.
The default is right-justified; a -
character here will make it left-justified.

An optional number, a width specifier
that says how many characters (minimum) this conversion should
result in.

An optional precision specifier in the form
of a period (.) followed by an optional decimal digit string
that says how many decimal digits should be displayed for
floating-point numbers. When using this specifier on a string,
it acts as a cutoff point, setting a maximum character limit to
the string. Additionally, the character to use when padding a
number may optionally be specified between the period and the
digit.

A type specifier that says what type the
argument data should be treated as. Possible types:

% - a literal percent character. No
argument is required.

b - the argument is treated as an
integer and presented as a binary number.

c - the argument is treated as an
integer and presented as the character with that ASCII
value.

d - the argument is treated as an
integer and presented as a (signed) decimal number.

e - the argument is treated as scientific
notation (e.g. 1.2e+2).
The precision specifier stands for the number of digits after the
decimal point since PHP 5.2.1. In earlier versions, it was taken as
number of significant digits (one less).

E - like %e but uses
uppercase letter (e.g. 1.2E+2).

f - the argument is treated as a
float and presented as a floating-point number (locale aware).

F - the argument is treated as a
float and presented as a floating-point number (non-locale aware).
Available since PHP 5.0.3.

g - shorter of %e and
%f.

G - shorter of %E and
%f.

o - the argument is treated as an
integer and presented as an octal number.

s - the argument is treated as and
presented as a string.

u - the argument is treated as an
integer and presented as an unsigned decimal number.

x - the argument is treated as an integer
and presented as a hexadecimal number (with lowercase
letters).

X - the argument is treated as an integer
and presented as a hexadecimal number (with uppercase
letters).

Variables will be co-erced to a suitable type for the specifier:

Type Handling

Type

Specifiers

string

s

integer

d,
u,
c,
o,
x,
X,
b

double

g,
G,
e,
E,
f,
F

Warning

Attempting to use a combination of the string and width specifiers with character sets that require more than one byte per character may result in unexpected results

The format string supports argument numbering/swapping. Here is an
example:

We now have a problem. The order of the placeholders in the
format string does not match the order of the arguments in the
code. We would like to leave the code as is and simply indicate
in the format string which arguments the placeholders refer to.
We would write the format string like this instead:

User Contributed Notes 60 notes

1. A plus sign ('+') means put a '+' before positive numbers while a minus sign ('-') means left justify. The documentation incorrectly states that they are interchangeable. They produce unique results that can be combined:

2. Padding with a '0' is different than padding with other characters. Zeros will only be added at the front of a number, after any sign. Other characters will be added before the sign, or after the number:

There are already some comments on using sprintf to force leading leading zeros but the examples only include integers. I needed leading zeros on floating point numbers and was surprised that it didn't work as expected.

Example:<?phpsprintf('%02d', 1);?>

This will result in 01. However, trying the same for a float with precision doesn't work:

<?phpsprintf('%02.2f', 1);?>

Yields 1.00.

This threw me a little off. To get the desired result, one needs to add the precision (2) and the length of the decimal seperator "." (1). So the correct pattern would be

This works more reliably than doing something like sprintf('%.15F', $value) as the latter may cut off significant digits for very small numbers, or prints bogus digits (meaning extra digits beyond what can reliably be represented in a floating point number) for very large numbers.

Note that when using the argument swapping, you MUST number every argument, otherwise sprintf gets confused. This only happens if you use number arguments first, then switch to a non-numbered, and then back to a numbered one.

I created this function a while back to save on having to combine mysql_real_escape_string onto all the params passed into a sprintf. it works literally the same as the sprintf other than that it doesn't require you to escape your inputs. Hope its of some use to people

A more complete and working version of mb_sprintf and mb_vsprintf. It should work with any "ASCII preserving" encoding such as UTF-8 and all the ISO-8859 charsets. It handles sign, padding, alignment, width and precision. Argument swapping is not handled.

// Split the format in two parts: $pre and $post by the first %-directive // We get also the matched groupslist ($pre, $sign, $filler, $align, $size, $precision, $type, $post) =preg_split("!\%(\+?)('.|[0 ]|)(-?)([1-9][0-9]*|)(\.[1-9][0-9]*|)([%a-zA-Z])!u",$format, 2, PREG_SPLIT_DELIM_CAPTURE) ;

I couldn't find what should be a WARNING in the documentation above, that if you have more specifiers than variables to match them sprintf returns NOTHING. This fact, IMHO, should also be noted under return values.

Be careful if you use the %f modifier to round decimal numbers as it (starting from 4.3.10) will no longer produce a float number if you set certain locales, so you can't accumulate the result. For example:

If you use the default padding specifier (a space) and then print it to HTML, you will notice that HTML does not display the multiple spaces correctly. This is because any sequence of white-space is treated as a single space.

To overcome this, I wrote a simple function that replaces all the spaces in the string returned by sprintf() with the character entity reference "&nbsp;" to achieve non-breaking space in strings returned by sprintf()

I'm roughly (I can see a couple cases where it comes out wierd) copying the syntax of Python's string formatting with a dictionary. The improvement over the several past attempts is that this one still respects all of the formating options, as you can see in my example.

And the error handling is really crappy (just an echo). I just threw this together so do with it what you will. =]

I needed a piece of code similar to the one Matt posted below, on the 10th of March, 2008. However, I wasn't completely satisfied with Matt's code (sorry, Matt! No offense intended!), because

1) I don't like to initialize variables when it's not really needed, and2) it contains two bugs.

What are the bugs?

First, Matt's code tests for count($vars) > 0, but if $var == "Hello world!", then count($var) == 1, but the foreach() will crash because $var has to be an array. So instead, my code tests for is_array($var).

Second, if a key in $vars is a prefix of any of the later keys in the array (like 'object' is the beginning of 'objective') then the str_replace messes things up. This is no big deal if your keys are hard-coded and you can make sure the keys don't interfere, but in my code the keys are variable. So I decided to first sort the array on a decreasing length of the key.

If possible, and if you're willing, you can also embed the key fields in the text between percent-signs, rather than prefixing the keys with one. Sorting is no longer necessary, and the execution time is less than half of the code above:

To jrust at rustyparts.com, note that if you're using a double-quoted string and *don't* escape the dollar sign with a backslash, $s and $d will be interpreted as variable references. The backslash isn't part of the format specifier itself but you do need to include it when you write the format string (unless you use single quotes).

Here's a clean, working version of functions to allow using named arguments instead of numeric ones. ex: instead of sprintf('%1$s', 'Joe');, we can use sprintf('%name$s', array('name' => 'Joe'));. I've provided 2 different versions: the first uses the php-like syntax (ex: %name$s), while the second uses the python syntax (ex: %(name)s).

// programmer did not supply a value for the named argument found in the format stringif (! array_key_exists($arg_key, $arg_nums)) {user_error("sprintfn(): Missing argument '${arg_key}'", E_USER_WARNING); return false; }

// replace the named argument with the corresponding numeric one$format = substr_replace($format, $replace = $arg_nums[$arg_key], $arg_pos, $arg_len);$pos = $arg_pos + strlen($replace); // skip to end of replacement for next iteration}

// programmer did not supply a value for the named argument found in the format stringif (! array_key_exists($arg_key, $arg_nums)) {user_error("sprintfn(): Missing argument '${arg_key}'", E_USER_WARNING); return false; }

Just to elaborate on downright's point about different meanings for %f, it appears the behavior changed significantly as of 4.3.7, rather than just being different on different platforms. Previously, the width specifier gave the number of characters allowed BEFORE the decimal. Now, the width specifier gives the TOTAL number of characters. (This is in line with the semantics of printf() in other languages.) See bugs #28633 and #29286 for more details.

To add to other notes below about floating point problems, I noted that %f and %F will apparently output a maximum precision of 6 as a default so you have to specify 1.15f (eg) if you need more.

In my case, the input (from MySQL) was a string with 15 digits of precision that was displayed with 6. Likely what happens is that the rounding occurs in the conversion to a float before it is displayed. Displaying it as 1.15f (or in my case, %s) shows the correct number.

handle with care :1. that function was designed mostly for utf-8. i guess it won't work with any static mb encoding.2. my configuration sets the mbstring.func_overload configuration directive to 7, so you may wish to replace substr, strlen, etc. with mb_* equivalents.3. since preg_* doesn't complies with mb strings, I used a '.+' in the regexp to symbolize an escaped filler character. That means, %'xy5s pattern will match, unfortunately. It is recomended to remove the '+', unless you are intending to use an mb char as filler.4. the filler fills at left, and only at left.5. I couldn't succeed with a preg_replace thing : the problem was to use the differents lengths of the string arguements in the same replacement, string or callback. That's why the code is much longuer than I expected.6. The pattern wil not match any %1\$s thing... just was too complicated for me.7. Although it has been tested, and works fine within the limits above, this is much more a draft than a end-user function. I would enjoy any improvment.

The test code below shows possibilities, and explains the problem that occures with an mb string argument in sprintf.

If you are going to create a counter which uses _symbols_ before actual digits (see, f.e., SpyLog.com counters - they are filling space with "." before, so the count like 12345 looks like "........12345"), you can use the following:

sprintf will complain about a lack in the number of arguments, this would be because of the %'s in the actual string. This can be a great benifit, but is also rather confusing if you dont realize this feature, and are passing questionable variables to sprintf (for, say perhaps logging). One way around this is using
ereg_replace("%","%%", $string); before
sending it off to sprintf. This is actually how i came across this as a problem - i had realized some time ago that i would have to test my $string for
%'s, but when running the %->%% replacement on a very large serialized object, my application timed out.
My solution was to use
sprintf("%d %s %s", $nbr, $string, $name);
but, there was a reason i originally had done this the other way - i suppose i'll find out soon enough

To convert / use / implement 64-bit signed 2's complement Long type values in PHP code, use the following code

// requires bcmath

/* java 64-bit long: The long data type is a 64-bit signed two's complement integer. It has a minimum value of -9,223,372,036,854,775,808 and a maximum value of 9,223,372,036,854,775,807 (inclusive). Use this data type when you need a range of values wider than those provided by int.*/

// now you can use $long as 64-bit signed long value by using bcmath functions// do not use php math funcs, they cant handle 64-bit long integer values// use bcadd bcsub etc from bcmath functions freely

Hope this helps people handling 64-bit long values retrieved from other languages like java, etc