downloads | documentation | faq | getting help | mailing lists | licenses | wiki | reporting bugs | php.net sites | conferences | my php.net

search for in the

sscanf> <soundex
[edit] Last updated: Fri, 17 May 2013

view this page in

sprintf

(PHP 4, PHP 5)

sprintfフォーマットされた文字列を返す

説明

string sprintf ( string $format [, mixed $args [, mixed $... ]] )

フォーマット文字列 format に基づき生成された文字列を返します。

パラメータ

format

フォーマット文字列は 0 個以上のディレクティブ(指示子) により構成されます。ディレクティブには、そのまま結果にコピーされる (% を除く) 通常の文字と変換指定子 (conversion specifications) があり、 取り出される際はどちらもそれ自身がパラメータとなります。このことは sprintf() の場合だけでなく printf() の場合も同様です。

各変換指定子は、パーセント記号 (%) の後に これらの要素が一つ以上続いたものになります。

  1. オプションの符号指定子。これは、 数値で符号 (- あるいは +) を使用するよう指定します。 デフォルトでは、数値が負の場合の - 符号のみが使用されます。 この指定子により、正の数にも強制的に + 符号をつけることができます。 これは PHP 4.3.0 で追加されました。
  2. オプションのパディング指定子。これは、 文字列が正しい長さになるまでどんな文字で埋めるかということを 指定します。これは空白かまたは 0 (文字 '0') のいずれかです。デフォルトでは空白で埋められます。 これ以外のパディング文字を指定するには、その文字の前に 単一引用符 (') を置きます。 後述の例を参照ください。
  3. オプションのアラインメント指定子。これは、 結果を左寄せまたは右寄せにしたい場合に指定します。 デフォルトは右寄せです。ここで - 文字を指定すると左寄せとなります。
  4. オプションの数字。これは表示幅指定子です。 結果を(最低)何桁にするかを指定します。
  5. オプションの精度指定子 (ピリオド (`.') に続けてオプションで桁数指定文字列を書いたもの)。 これは、浮動小数点数に対して数字を何桁まで表示するかを指定します。 文字列に対して使用した場合は、これは切り捨て位置として働きます。 この文字数を超える文字を切り捨てられます。
  6. 型指定子。引数を何の型として扱うかを指定します。 指定できる型を以下に示します。

    • % - パーセント文字。引数は不要です。
    • b - 引数を整数として扱い、 2 進数として表現します。
    • c - 引数を整数として扱い、その ASCII 値の文字として表現します。
    • d - 引数を整数として扱い、 10 進数として表現します。
    • e - 引数を科学記法として扱います (例 1.2e+2)。 精度の指定子は、PHP 5.2.1 以降では小数点以下の桁数を表します。 それより前のバージョンでは、有効数字の桁数 (ひとつ小さい値) を意味していました。
    • E - %e と同じですが、 大文字を使います (例 1.2E+2)。
    • u - 引数を整数として扱い、符号無しの 10 進数として表現します。
    • f - 引数を double として扱い、 浮動小数点数として表現します。
    • F - 引数を float として扱い、 浮動小数点数として表現します (ロケールに依存しません)。 PHP 4.3.10 および PHP 5.0.3 以降で使用可能です。
    • g - %e および %f の短縮形。
    • G - %E および %f の短縮形。
    • o - 引数を整数として扱い、 8 進数として表現します。
    • s - 引数を文字列として扱い、表現します。
    • x - 引数を整数として扱い、16 進数として (小文字で)表現します。
    • X - 引数を整数として扱い、16 進数として (大文字で)表現します。

フォーマット文字列における引数の 番号付け/交換 をサポートしています。以下に例を示します。

例1 引数の交換

<?php
$num 
5;
$location 'tree';

$format 'There are %d monkeys in the %s';
echo 
sprintf($format$num$location);
?>
この出力は、"There are 5 monkeys in the tree" のようになります。 ここで、フォーマット文字列が別のファイルにある場合を考えてみましょう。 これは、出力を国際化したりする場合に行われる可能性があります。 たとえばフォーマット文字列が次のように書き換えられたとすると、

例2 引数の交換

<?php
$format 
'The %s contains %d monkeys';
echo 
sprintf($format$num$location);
?>
ここで、問題が発生します。フォーマット文字列における置換指示子の順番は、 コードにおける引数の順番と一致していません。 だからといってコードを変更するのではなく、 むしろ置換指示子が参照するフォーマット文字列のほうで指示を行う方が望ましいでしょう。 フォーマット文字列を次のように書き換えてみましょう。

例3 引数の交換

<?php
$format 
'The %2$s contains %1$d monkeys';
echo 
sprintf($format$num$location);
?>
こうすることによるもうひとつの利点は、 同じ置換指示子を複数回使用する際にコードに引数を追加せずにすむことです。 例えば、次のようになります。

例4 引数の交換

<?php
$format 
'The %2$s contains %1$d monkeys.
           That\'s a nice %2$s full of %1$d monkeys.'
;
echo 
sprintf($format$num$location);
?>
引数の交換を使うときには、 位置指定子 n$ をパーセント記号 (%) の直後に置かなければならず、 間に他の指定を入れてはいけません。次の例を示します。

例5 位置指定子と他の指定との共用

<?php
$format 
'The %2$s contains %1$04d monkeys';
echo 
sprintf($format$num$location);
?>

上の例の出力は以下となります。

The tree contains 0005 monkeys

注意:

PHP_INT_MAX より大きい位置指定子を指定すると、 sprintf() は警告を発します。

args

...

返り値

フォーマット文字列 format に基づき生成された文字列を返します。

変更履歴

バージョン 説明
4.0.6 引数の 番号付け/交換 をサポートするようになりました。

例6 printf() のさまざまな例

<?php
$n 
=  43951789;
$u = -43951789;
$c 65// ASCII コードの 65 は 'A' です

// %% に注目しましょう。これは、リテラル '%' を文字として出力します
printf("%%b = '%b'\n"$n); // 2 進表現
printf("%%c = '%c'\n"$c); // ascii 文字を表示します。chr() 関数と同じです
printf("%%d = '%d'\n"$n); // 標準の整数表現
printf("%%e = '%e'\n"$n); // 科学記法
printf("%%u = '%u'\n"$n); // 正の整数の、符号なし整数表現
printf("%%u = '%u'\n"$u); // 負の整数の、符号なし整数表現
printf("%%f = '%f'\n"$n); // 浮動小数点表現
printf("%%o = '%o'\n"$n); // 8 進表現
printf("%%s = '%s'\n"$n); // 文字列表現
printf("%%x = '%x'\n"$n); // 16 進表現 (小文字)
printf("%%X = '%X'\n"$n); // 16 進表現 (大文字)

printf("%%+d = '%+d'\n"$n); // 正の整数に符号指定子を使用
printf("%%+d = '%+d'\n"$u); // 負の整数に符号指定子を使用
?>

上の例の出力は以下となります。

%b = '10100111101010011010101101'
%c = 'A'
%d = '43951789'
%e = '4.39518e+7'
%u = '43951789'
%u = '4251015507'
%f = '43951789.000000'
%o = '247523255'
%s = '43951789'
%x = '29ea6ad'
%X = '29EA6AD'
%+d = '+43951789'
%+d = '-43951789'

例7 printf() の文字列指定子

<?php
$s 
'monkey';
$t 'many monkeys';

printf("[%s]\n",      $s); // 標準の文字列出力
printf("[%10s]\n",    $s); // 空白を使用して右詰め
printf("[%-10s]\n",   $s); // 空白を使用して左詰め
printf("[%010s]\n",   $s); // ゼロ埋めは文字列でも可能です
printf("[%'#10s]\n",  $s); // ゼロの代わりに独自の文字 '#' で埋めます
printf("[%10.10s]\n"$t); // 左詰めを行い、10 文字以上は切り捨てます
?>

上の例の出力は以下となります。

[monkey]
[    monkey]
[monkey    ]
[0000monkey]
[####monkey]
[many monke]

例8 sprintf(): 整数のゼロ埋め

<?php
$isodate 
sprintf("%04d-%02d-%02d"$year$month$day);
?>

例9 sprintf(): 通貨をフォーマットする例

<?php
$money1 
68.75;
$money2 54.35;
$money $money1 $money2;
// echo $money は "123.1" を出力します。
$formatted sprintf("%01.2f"$money);
// echo $formatted は "123.10"を出力します
?>

例10 sprintf(): 科学記法

<?php
$number 
362525200;

echo 
sprintf("%.3e"$number); // 3.625e+8 を出力します
?>

参考

  • printf() - フォーマット済みの文字列を出力する
  • sscanf() - フォーマット文字列に基づき入力を処理する
  • fscanf() - フォーマットに基づきファイルからの入力を処理する
  • vsprintf() - フォーマットされた文字列を返す
  • number_format() - 数字を千位毎にグループ化してフォーマットする



sscanf> <soundex
[edit] Last updated: Fri, 17 May 2013
 
add a note add a note User Contributed Notes sprintf - [70 notes]
up
8
Alex R. Gibbs
3 months ago
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:

<?php
echo sprintf ("|%+4d|%+4d|\n",   1, -1);
echo
sprintf ("|%-4d|%-4d|\n",   1, -1);
echo
sprintf ("|%+-4d|%+-4d|\n", 1, -1);
?>

outputs:

|  +1|  -1|
|1   |-1  |
|+1  |-1  |

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:

<?php
echo sprintf ("|%04d|\n",   -2);
echo
sprintf ("|%':4d|\n",  -2);
echo
sprintf ("|%-':4d|\n", -2);

// Specifying both "-" and "0" creates a conflict with unexpected results:
echo sprintf ("|%-04d|\n",  -2);

// Padding with other digits behaves like other non-zero characters:
echo sprintf ("|%-'14d|\n", -2);
echo
sprintf ("|%-'04d|\n", -2);
?>

outputs:

|-002|
|::-2|
|-2::|
|-2  |
|-211|
|-2  |
up
3
krzysiek dot 333 at gmail dot com - zryty dot hekko dot pl
1 year ago
Encoding and decoding IP adress to format: 1A2B3C4D (mysql column: char(8) )

<?php
function encode_ip($dotquad_ip)
{
   
$ip_sep = explode('.', $dotquad_ip);
    return
sprintf('%02x%02x%02x%02x', $ip_sep[0], $ip_sep[1], $ip_sep[2], $ip_sep[3]);
}

function
decode_ip($int_ip)
{
   
$hexipbang = explode('.', chunk_split($int_ip, 2, '.'));
    return
hexdec($hexipbang[0]). '.' . hexdec($hexipbang[1]) . '.' . hexdec($hexipbang[2]) . '.' . hexdec($hexipbang[3]);
}
?>
up
3
Jay Gilford
3 years ago
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

<?php
function mressf()
{
   
$args = func_get_args();
    if (
count($args) < 2)
        return
false;
   
$query = array_shift($args);
   
$args = array_map('mysql_real_escape_string', $args);
   
array_unshift($args, $query);
   
$query = call_user_func_array('sprintf', $args);
    return
$query;
}
?>

Regards
Jay
Jaygilford.com
up
3
php at sharpdreams dot com
9 years ago
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.

<?php
$sql
= sprintf( "select * from %1\$s left join %2\$s on( %1\$s.id = %2\$s.midpoint ) where %1\$s.name like '%%%s%%' and %2\$s.tagname is not null", "table1", "table2", "bob" );
// Wont work:
// Sprintf will complain about not enough arguments.
$sql = sprintf( "select * from %1\$s left join %2\$s on( %1\$s.id = %2\$s.midpoint ) where %1\$s.name like '%%%3\$s%%' and %2\$s.tagname is not null", "table1", "table2", "bob" );
// Will work: note the %3\$s
?>
up
2
christian at wenz dot org
8 years ago
@ henke dot andersson at comhem dot se: Use vprintf()/vsprintf() for that.
up
1
John Walker
3 years ago
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.
up
1
MelTraX
4 years ago
<?php
 
// parses a string meant for printf and returns an array of found parameters (or NULL if it contains syntax errors)
 
function parsePrintfParameters($string) {
   
$valid = '/^(?:%%|%(?:[0-9]+\$)?[+-]?(?:[ 0]|\'.)?-?[0-9]*(?:\.[0-9]+)?[bcdeufFosxX])/';
   
$originalString = $string;

   
$result = array();
    while(
strlen($string)) {
      if(!
$string = preg_replace('/^[^%]*/', '', $string))
        break;

      if(
preg_match($valid, $string, $matches)) {
       
$result[] = $matches[0];
       
$string = substr($string, strlen($matches[0]));
      } else {
       
error(sprintf('"%s" has an error near "%s".', $originalString, $string));
        return
NULL;
      }
    }
    return
$result;
  }
?>
up
1
php at mikeboers dot com
4 years ago
And continuing on the same theme of a key-based 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. =]

<?php

function sprintf_array($string, $array)
{
   
$keys    = array_keys($array);
   
$keysmap = array_flip($keys);
   
$values  = array_values($array);
   
    while (
preg_match('/%\(([a-zA-Z0-9_ -]+)\)/', $string, $m))
    {   
        if (!isset(
$keysmap[$m[1]]))
        {
            echo
"No key $m[1]\n";
            return
false;
        }
       
       
$string = str_replace($m[0], '%' . ($keysmap[$m[1]] + 1) . '$', $string);
    }
   
   
array_unshift($values, $string);
   
var_dump($values);
    return
call_user_func_array('sprintf', $values);
}

echo
sprintf_array('4 digit padded number: %(num)04d ', array('num' => 42));

?>

Cheers!
up
1
matt
5 years ago
Was looking for a assoc way of using sprintf but couldnt find one, probably wasnt looking hard enough so came up with this. Very very simple indeed...

<?php

function sprintf2($str='', $vars=array(), $char='%')
{
    if (!
$str) return '';
    if (
count($vars) > 0)
    {
        foreach (
$vars as $k => $v)
        {
           
$str = str_replace($char . $k, $v, $str);
        }
    }

    return
$str;
}

echo
sprintf2('Hello %your_name my name is %my_name! I am %my_age, how old are you? I like %object!', array(
   
'your_name' => 'Ben',
   
'my_name' => 'Matt',
   
'my_age' => '21',
   
'object' => 'food'
));

// Hello Ben my name is Matt! I am 21, how old are you? I like food!

?>

Looks nice anyway :)
up
1
bknakkerNO at SPAMgmail dot com
6 years ago
Note that in PHP5 (.1.4 for me) sprintf will not use the __toString function of an object.

<?php
class pr{
private
$l;
public function
__construct($l)
{
$this->l=$l;
}
public function
__toString()
{
return
$this->l;
}
}
echo new
pr('This works!!'); //This will display 'This works!!'
echo sprintf(new pr('This doesnt')); // will display 'Object'
?>

Be careful with that!
up
1
mauf at franzoni dot info
7 years ago
The format of floating values has been previously reporting as depending on platform (linux / windows) yet I see it changes within two linux systems depending on the version:
In V4.2.2 "%3.2" displays 3 integers and two decimals (i.e. the first digit represents just the number of integer digits), on V4.4.1 the same displays (and justifies the string to) a three character string (i.e. the first digit is the total lenght of the number, including the decimal dot).

Maybe someone may better specify which version this happens from.
up
1
webmaster at cafe-clope dot net
7 years ago
trying to fix the multibyte non-compliance of sprintf, I came to that :

<?php
function mb_sprintf($format) {
   
$argv = func_get_args() ;
   
array_shift($argv) ;
    return
mb_vsprintf($format, $argv) ;
}

function
mb_vsprintf($format, $argv) {
   
$newargv = array() ;
   
   
preg_match_all("`\%('.+|[0 ]|)([1-9][0-9]*|)s`U", $format, $results, PREG_SET_ORDER) ;
   
    foreach(
$results as $result) {
        list(
$string_format, $filler, $size) = $result ;
        if(
strlen($filler)>1)
           
$filler = substr($filler, 1) ;
        while(!
is_string($arg = array_shift($argv)))
           
$newargv[] = $arg ;
       
$pos = strpos($format, $string_format) ;
       
$format = substr($format, 0, $pos)
                  . (
$size ? str_repeat($filler, $size-strlen($arg)) : '')
                    .
str_replace('%', '%%', $arg)
                    .
substr($format, $pos+strlen($string_format))
                    ;
    }
       
    return
vsprintf($format, $newargv) ;
}

?>

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.

<?php
header
("content-type:text/plain; charset=UTF-8") ;
$mb_string = "xxx" ;
echo
sprintf("%010s", $mb_string), " [octet-size: ", str_sizeof($mb_string) , " ; count: ", strlen(sprintf("%010s", $mb_string)), " characters]\n" ;
echo
mb_sprintf("%010s", $mb_string), " [octet-size: ", str_sizeof($mb_string) , " ; count: ", strlen(mb_sprintf("%010s", $mb_string)), " characters]\n" ;
echo
"\n" ;
echo
mb_sprintf("%''10s\n%'010s\n%'10s\n%10d\n%'x10s\n%010s\n% 10s\n%010s\n%'1s\n", "zero", "one", "two", 3, "four", "ve", "%s%i%x", "ve", "eight") ;
?>
up
1
Pacogliss
8 years ago
Just a reminder for beginners : example 6 'printf("[%10s]\n",    $s);' only works (that is, shows out the spaces) if you put the html '<pre></pre>' tags ( head-scraping time saver ;-).
up
1
Gkeeper80
8 years ago
When using sprintf with padding, it's important to note that specifying the length of your padding does not restrict the length of your output.

For example:
$var = 'test';
$output sprintf("%03s", $var);

print $output;

Produces:
test

NOT:
est

This may seem intuitive for working with numbers, but not neccesarily when working with strings.
up
1
info at nospam dot webtip dot dk
10 years ago
If you want to format a phonenumber with spaces, use chunk_split() which splits a string into smaller chunks. It's much simpler than using sprintf.

$phone = "12345678";

chunk_split ($phone, 2);

will return 12 34 56 78
up
1
no dot email dot address at example dot com
10 years ago
Using argument swapping in sprintf() with gettext: Let's say you've written the following script:

<?php
$var
= sprintf(gettext("The %2\$s contains %1\$d monkeys"), 2, "cage");
?>

Now you run xgettext in order to generate a .po file. The .po file will then look like this:

#: file.php:9
#, ycp-format
msgid "The %2\\$s contains %1\\$d monkeys"
msgstr ""

Notice how an extra backslash has been added by xgettext.

Once you've translated the string, you must remove all backslashes from the ID string as well as the translation, so the po file will look like this:

#: file.php:9
#, ycp-format
msgid "The %2$s contains %1$d monkeys"
msgstr "Der er %1$d aber i %2$s"

Now run msgfmt to generate the .mo file, restart Apache to remove the gettext cache if necessary, and you're off.
up
1
tjchamberlain.hotmail@com
12 years ago
It is worth noting that "%5.2f" will result in a string 8 characters long (5 then the '.' then 2), not 5 characters as you might expect.
up
3
nate at frickenate dot com
3 years ago
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).

<?php

/**
 * version of sprintf for cases where named arguments are desired (php syntax)
 *
 * with sprintf: sprintf('second: %2$s ; first: %1$s', '1st', '2nd');
 *
 * with sprintfn: sprintfn('second: %second$s ; first: %first$s', array(
 *  'first' => '1st',
 *  'second'=> '2nd'
 * ));
 *
 * @param string $format sprintf format string, with any number of named arguments
 * @param array $args array of [ 'arg_name' => 'arg value', ... ] replacements to be made
 * @return string|false result of sprintf call, or bool false on error
 */
function sprintfn ($format, array $args = array()) {
   
// map of argument names to their corresponding sprintf numeric argument value
   
$arg_nums = array_slice(array_flip(array_keys(array(0 => 0) + $args)), 1);

   
// find the next named argument. each search starts at the end of the previous replacement.
   
for ($pos = 0; preg_match('/(?<=%)([a-zA-Z_]\w*)(?=\$)/', $format, $match, PREG_OFFSET_CAPTURE, $pos);) {
       
$arg_pos = $match[0][1];
       
$arg_len = strlen($match[0][0]);
       
$arg_key = $match[1][0];

       
// programmer did not supply a value for the named argument found in the format string
       
if (! 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
   
}

    return
vsprintf($format, array_values($args));
}

/**
 * version of sprintf for cases where named arguments are desired (python syntax)
 *
 * with sprintf: sprintf('second: %2$s ; first: %1$s', '1st', '2nd');
 *
 * with sprintfn: sprintfn('second: %(second)s ; first: %(first)s', array(
 *  'first' => '1st',
 *  'second'=> '2nd'
 * ));
 *
 * @param string $format sprintf format string, with any number of named arguments
 * @param array $args array of [ 'arg_name' => 'arg value', ... ] replacements to be made
 * @return string|false result of sprintf call, or bool false on error
 */
function sprintfn ($format, array $args = array()) {
   
// map of argument names to their corresponding sprintf numeric argument value
   
$arg_nums = array_slice(array_flip(array_keys(array(0 => 0) + $args)), 1);

   
// find the next named argument. each search starts at the end of the previous replacement.
   
for ($pos = 0; preg_match('/(?<=%)\(([a-zA-Z_]\w*)\)/', $format, $match, PREG_OFFSET_CAPTURE, $pos);) {
       
$arg_pos = $match[0][1];
       
$arg_len = strlen($match[0][0]);
       
$arg_key = $match[1][0];

       
// programmer did not supply a value for the named argument found in the format string
       
if (! 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
   
}

    return
vsprintf($format, array_values($args));
}

?>
up
1
Hayley Watson
11 months ago
If you use argument numbering, then format specifications with the same number get the same argument; this can save repeating the argument in the function call.

<?php

$pattern
= '%1$s %1$\'#10s %1$s!';

printf($pattern, "badgers");
?>
up
1
jfgrissom at gmail dot com
3 years ago
I had a nightmare trying to find the two's complement of a 32 bit number.

I got this from http://www.webmasterworld.com/forum88/13334.htm (credit where credit is due... =P  )

Quote: ...find out the 2's complement of any number, which is -(pow(2, n) - N) where n is the number of bits and N is the number for which to find out its 2's complement.

This worked magic for me... previously I was trying to use

sprintf ("%b",$32BitDecimal);
But it always returned 10000000000000000000000 when the $32BitDecimal value got above 2,000,000,000.

This -(pow(2, n) - N)
Worked remarkably well and was very accurate.

Hope this helps someone fighting with two's complement in PHP.
up
1
splogamurugan at gmail dot com
4 years ago
$format = 'There are %1$d monkeys in the %s and %s ';
printf($format, 100, 'Chennai', 'Bangalore');

Expecting to output
"There are 100 monkeys in the Chennai and bangalore"

But, this will output
"There are 100 monkeys in the 100 and Chennai"

Because, the second and Third specifiers takes 1rst and 2nd arguments. Because it is not assigned with any arguments.
up
1
scott dot gardner at mac dot com
5 years ago
In the last example of Example#6, there is an error regarding the output.

printf("[%10.10s]\n", $t); // left-justification but with a cutoff of 10 characters

This outputs right-justified.

In order to output left-justified:

printf("[%-10.10s]\n", $t);
up
0
dwieeb at gmail dot com
2 years ago
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()

<?php
//Here is the function:
function sprintf_nbsp() {
  
$args = func_get_args();
   return
str_replace(' ', '&nbsp;', vsprintf(array_shift($args), array_values($args)));
}

//Usage (exactly like sprintf):
$format = 'The %d monkeys are attacking the [%10s]!';
$str = sprintf_nbsp($format, 15, 'zoo');
echo
$str;
?>

The above example will output:
The 15 monkeys are attacking the [       zoo]!

<?php
//The variation that prints the string instead of returning it:
function printf_nbsp() {
  
$args = func_get_args();
   echo
str_replace(' ', '&nbsp;', vsprintf(array_shift($args), array_values($args)));
}
?>
up
0
jaimthorn at yahoo dot com
4 years ago
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, and
2) 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.

<?php

function cmp($a, $b)
{
    return
strlen($b) - strlen($a);
}

function
sprintf2($str, $vars, $char = '%')
{
    if(
is_array($vars))
    {
       
uksort($vars, "cmp");

        foreach(
$vars as $k => $v)
        {
           
$str = str_replace($char . $k, $v, $str);
        }
    }

    return
$str;
}

echo
sprintf2( 'Hello %your_name, my name is %my_name! I am %my_age, how old are you? I like %object and I want to %objective_in_life!'
            
, array( 'your_name'         => 'Matt'
                   
, 'my_name'           => 'Jim'
                   
, 'my_age'            => 'old'
                   
, 'object'            => 'women'
                   
, 'objective_in_life' => 'write code'
                   
)
             );

?>

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:

<?php

function sprintf3($str, $vars, $char = '%')
{
   
$tmp = array();
    foreach(
$vars as $k => $v)
    {
       
$tmp[$char . $k . $char] = $v;
    }
    return
str_replace(array_keys($tmp), array_values($tmp), $str);
}

echo
sprintf3( 'Hello %your_name%, my name is %my_name%! I am %my_age%, how old are you? I like %object% and I want to %objective_in_life%!'
            
, array( 'your_name'         => 'Matt'
                   
, 'my_name'           => 'Jim'
                   
, 'my_age'            => 'old'
                   
, 'object'            => 'women'
                   
, 'objective_in_life' => 'write code'
                   
)
             );
?>

If you're willing to embed the keys in the text, you may also be willing to embed the keys themselves in percent signs, thus shaving off another 30% of the execution time:

<?php

function sprintf4($str, $vars)
{
    return
str_replace(array_keys($vars), array_values($vars), $str);
}

echo
sprintf4( 'Hello %your_name%, my name is %my_name%! I am %my_age%, how old are you? I like %object% and I want to %objective_in_life%!'
            
, array( '%your_name%'         => 'Matt'
                   
, '%my_name%'           => 'Jim'
                   
, '%my_age%'            => 'old'
                   
, '%object%'            => 'women'
                   
, '%objective_in_life%' => 'write code'
                   
)
             );
?>

Of course, by now the sprintf function is no longer something you'd want to write to mum and dad about...
up
0
kouber at php dot net
10 years ago
If you want to cut all the zeros off the end of a float, but not losing any sensitive information, use this:

<?
function cutzero($value) {
    return
preg_replace("/(\.\d+?)0+$/", "$1", $value)*1;
}
?>

Some examples:

<?
cutzero
("4.7600");     // returns 4.76
cutzero("4.7604")      // returns 4.7604
cutzero("4.7000");     // returns 4.7
cutzero("4.0000");     // returns 4
?>
up
0
Andrew dot Wright at spamsux dot atnf dot csiro dot au
10 years ago
An error in my last example:
$b = sprintf("%30.s", $a);
will only add enough spaces before $a to pad the spaces + strlen($a) to 30 places.

My method of centering fixed text in a 72 character width space is:

$a = "Some string here";
$lwidth = 36; // 72/2
$b = sprintf("%".($lwidth + round(strlen($a)/2)).".s", $a);
up
-1
ignat dot scheglovskiy at gmail dot com
7 months ago
Here is an example how alignment, padding and precision specifier can be used to print formatted list of items:

<?php

$out
= "The Books\n";
$books = array("Book 1", "Book 2", "Book 3");
$pages = array("123 pages ", "234 pages", "345 pages");
for (
$i = 0; $i < count($books); $i++) {
   
$out .= sprintf("%'.-20s%'.7.4s\n", $books[$i], $pages[$i]);
}
echo
$out;

// Outputs:
//
// The Books
// Book 1.................123
// Book 2.................234
// Book 3.................345
?>
up
-1
keeper at odi dot com dot br
11 years ago
Took me a while to find this out.
hope will save someones time.
IT ADD A CARACRER TO THE END OF A STRING

$x = sprintf("%'x-10s", "a");
echo $x;
up
0
timo dot frenay at gmail dot com
2 years ago
Here is how to print a floating point number with 16 significant digits regardless of magnitude:

<?php
    $result
= sprintf(sprintf('%%.%dF', max(15 - floor(log10($value)), 0)), $value);
?>

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.
up
0
geertdd at gmail dot com
2 years ago
Note that when using a sign specifier, the number zero is considered positive and a "+" sign will be prepended to it.

<?php
printf
('%+d', 0); // +0
?>
up
0
Astone
3 years ago
When you're using Google translator, you have to 'escape' the 'conversion specifications' by putting <span class="notranslate"></span> around them.

Like this:

<?php

function getGoogleTranslation($sString, $bEscapeParams = true)
{
   
// "escape" sprintf paramerters
   
if ($bEscapeParams)
    {
       
$sPatern = '/(?:%%|%(?:[0-9]+\$)?[+-]?(?:[ 0]|\'.)?-?[0-9]*(?:\.[0-9]+)?[bcdeufFosxX])/';       
       
$sEscapeString = '<span class="notranslate">$0</span>';
       
$sString = preg_replace($sPatern, $sEscapeString, $sString);
    }

   
// Compose data array (English to Dutch)
   
$aData = array(
       
'v'            => '1.0',
       
'q'            => $sString,
       
'langpair'    => 'en|nl',
    );

   
// Initialize connection
   
$rService = curl_init();
   
   
// Connection settings
   
curl_setopt($rService, CURLOPT_URL, 'http://ajax.googleapis.com/ajax/services/language/translate');
   
curl_setopt($rService, CURLOPT_RETURNTRANSFER, true);
   
curl_setopt($rService, CURLOPT_POSTFIELDS, $aData);
   
   
// Execute request
   
$sResponse = curl_exec($rService);

   
// Close connection
   
curl_close($rService);
   
   
// Extract text from JSON response
   
$oResponse = json_decode($sResponse);
    if (isset(
$oResponse->responseData->translatedText))
    {
       
$sTranslation = $oResponse->responseData->translatedText;
    }
    else
    {
       
// If some error occured, use the original string
       
$sTranslation = $sString;
    }
   
   
// Replace "notranslate" tags
   
if ($bEscapeParams)
    {
       
$sEscapePatern = '/<span class="notranslate">([^<]*)<\/span>/';
       
$sTranslation = preg_replace($sEscapePatern, '$1', $sTranslation);
    }
   
   
// Return result
   
return $sTranslation;
}

?>

Thanks to MelTraX for defining the RegExp!
up
0
viktor at textalk dot com
4 years ago
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.

<?php
if (!function_exists('mb_sprintf')) {
  function
mb_sprintf($format) {
     
$argv = func_get_args() ;
     
array_shift($argv) ;
      return
mb_vsprintf($format, $argv) ;
  }
}
if (!
function_exists('mb_vsprintf')) {
 
/**
   * Works with all encodings in format and arguments.
   * Supported: Sign, padding, alignment, width and precision.
   * Not supported: Argument swapping.
   */
 
function mb_vsprintf($format, $argv, $encoding=null) {
      if (
is_null($encoding))
         
$encoding = mb_internal_encoding();

     
// Use UTF-8 in the format so we can use the u flag in preg_split
     
$format = mb_convert_encoding($format, 'UTF-8', $encoding);

     
$newformat = ""; // build a new format in UTF-8
     
$newargv = array(); // unhandled args in unchanged encoding

     
while ($format !== "") {
     
       
// Split the format in two parts: $pre and $post by the first %-directive
        // We get also the matched groups
       
list ($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) ;

       
$newformat .= mb_convert_encoding($pre, $encoding, 'UTF-8');
       
        if (
$type == '') {
         
// didn't match. do nothing. this is the last iteration.
       
}
        elseif (
$type == '%') {
         
// an escaped %
         
$newformat .= '%%';
        }
        elseif (
$type == 's') {
         
$arg = array_shift($argv);
         
$arg = mb_convert_encoding($arg, 'UTF-8', $encoding);
         
$padding_pre = '';
         
$padding_post = '';
         
         
// truncate $arg
         
if ($precision !== '') {
           
$precision = intval(substr($precision,1));
            if (
$precision > 0 && mb_strlen($arg,$encoding) > $precision)
             
$arg = mb_substr($precision,0,$precision,$encoding);
          }
         
         
// define padding
         
if ($size > 0) {
           
$arglen = mb_strlen($arg, $encoding);
            if (
$arglen < $size) {
              if(
$filler==='')
                 
$filler = ' ';
              if (
$align == '-')
                 
$padding_post = str_repeat($filler, $size - $arglen);
              else
                 
$padding_pre = str_repeat($filler, $size - $arglen);
            }
          }
         
         
// escape % and pass it forward
         
$newformat .= $padding_pre . str_replace('%', '%%', $arg) . $padding_post;
        }
        else {
         
// another type, pass forward
         
$newformat .= "%$sign$filler$align$size$precision$type";
         
$newargv[] = array_shift($argv);
        }
       
$format = strval($post);
      }
     
// Convert new format back from UTF-8 to the original encoding
     
$newformat = mb_convert_encoding($newformat, $encoding, 'UTF-8');
      return
vsprintf($newformat, $newargv);
  }
}
?>
up
0
remy dot damour at -please-no-spam-laposte dot net
4 years ago
With printf() and sprintf() functions, escape character is not backslash '\' but rather '%'.

Ie. to print '%' character you need to escape it with itself:
<?php
printf
('%%%s%%', 'koko'); #output: '%koko%'
?>
up
0
ant at loadtrax dot com
4 years ago
Rounding seems a little inconsistent, so beware:

$ php -a

php> print round(1.0*20*1.175/100,2);
0.24
php > print sprintf("%.2f",1.0*20*1.175/100);
0.23
php > print sprintf("%.0f",1.0*20*1.175);
24

I get round this by doing the round first, then doing the sprintf.
up
0
ranema at ubuntu dot polarhome dot com
5 years ago
It's very comfortible for long Sql queries:

<?php
$_gQuery
= "UPDATE `x` SET `a` = %i AND `b` = '%s' WHERE `my` = '%s';"; // ........

mysql_query( sprintf( $_gQuery, 10, 'a', 'rrrr' ) );
?>

But if you have a short query, then it would be much faster to append your data by using `.`.

<?php
$_gQuery
= 'SELECT COUNT(*) FROM `' . $_gName . '`;';
?>
up
0
me at umarfarooq dot net
5 years ago
/**
This function returns a formated  string with the legnth you specify
@string holds the string which you want to format
@len holds the length you want to format
**/
function formatString($string, $len)
{
    if (strlen($string) < $len)
    {
        $addchar=($len - strlen($string)) ;
        for ($i = 0; $i < $addchar; $i++)
        {
            $string=sprintf("$string%s", "0");
        }
    }
   
    if (strlen($string) > $len)
    {
        $string=substr($string,0,$len);
    }
   
    return $string;   
}
up
0
Thomas Breuss
6 years ago
Note:
If you want to use % in sprintf, you have to "quote" it like %%.

Example:
echo sprintf("Green => %d%%'", 50);

Output:
Green => 50%
up
0
SWestrup
6 years ago
In response to Anonymous, who claimed that:

  printf("[%s]\n", str_pad('Hello', 20));

and

  printf("[%-20s]\n", 'Hello');

are the same thing: you've missed the point.

They're only the same when the amount of padding is a known constant. When its a variable (or an expression), its often much more convenient to be able to write:

  printf("[%-*s]\n", 3*$n+2, "Hello");

than what you have to go through now, which is either:

  $t = 3*$n+2;
  printf("[%-{$t}s]\n","Hello");

or

  printf("[%s]\n", str_pad('Hello', 3*$n+2));
up
0
Anonymous
6 years ago
In response to Fredrik Rambris in the com top domain:

<?php

//Your code:

printf("[%s]\n", str_pad('Hello', 20));

//Is the same as:

printf("[%-20s]\n", 'Hello');

?>
up
0
Moore (at) Hs-Furtwangen (dot) De
6 years ago
Here a litle function that might come handy one time:
It gives back a String and adds a <BR> (you can change it to <br />) to every line end. And it adds $num blanks to the front of the next line.

<?php
 
function nl2brnl($text, $num)
  {
   return
preg_replace("/\\r\\n|\\n|\\r/", sprintf("% -".(5+$num)."s","<BR>\\n"), $text);
  }

$a = " one\\n two\\r\\n three";

$b = nl2brnl($a, 2);

var_dump($b);

/* output will be:
string(30) " one<BR>
   two<BR>
   three"
*/

echo "  <P>\\n   ";
echo
$b

/* output will be:
  <P>
   one<BR>
   two<BR>
   three
*/
?>

Is helpfull for avouding code_soup.
up
0
darkfalconIV at hotmail dot com
7 years ago
henke dot andersson

You can accomplish feeding it array if you use call_user_func_array. Not exactly a `clean' option, but it does work.
up
0
tim dot brouckaert dot NOSPAM at gmail dot com
7 years ago
If you want to center align some text using the printf or sprintf functions, you can just use the following:

function center_text($word){
    $tot_width = 30;
    $symbol = "-";
    $middle = round($tot_width/2);
    $length_word = strlen($word);
    $middle_word = round($length_word / 2);
    $last_position = $middle + $middle_word;
    $number_of_spaces = $middle - $middle_word;

    $result = sprintf("%'{$symbol}{$last_position}s", $word);
        for ($i = 0; $i < $number_of_spaces; $i++){
            $result .= "$symbol";
        }
    return $result;
}

$string = "This is some text";
print center_text($string);

off course you can modify the function to use more arguments.
up
0
david at rayninfo dot co dot uk
7 years ago
Using sprintf to force leading leading zeros

foreach (range(1, 10) as $v) {echo "<br>tag_".sprintf("%02d",$v);}

displays
tag_01
tag_02
tag_03
.. etc
up
0
downright at comcast dot net
8 years ago
Just thought I'd give a heads up for anyone doing cross platform applications.

sprintf spacing is different numerically with Windows and Linux.

Linux aligned correctly:
$ol = sprintf ("%-6s|%11.2f|%11.2f|%11.2f|%11.2f|%11.2f|%11.2f|%11.2f|%11.2f\n",

Windows aligned correctly:
$ol = sprintf ("%-6s|%14.2f|%14.2f|%14.2f|%14.2f|%14.2f|%14.2f|%14.2f|%14.2f\n",

As you can see the strings are fine for spacing, however, the numbers need a difference of 3 in order to have the same amount of spaces.

I noticed this after using sprintf to format a header for a web app I was working on.  On windows it fit, however, when it came to linux it was MUCH larger than the header.
up
0
jrpozo at conclase dot net
8 years ago
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:

setlocale(LC_ALL, 'es_ES');
echo(sprintf("%.2f", 13.332) + sprintf("%.2f", 14.446))

gives 27 instead of 27.78, so use %F instead.
up
0
rex
8 years ago
Note, if you are just looking for something to pad out a string consider str_pad.

From testing, it seems faster and was more intuitive to use (for example, making it pad the begining or end of a string... with sprintf you would have to use negative indexes)
up
0
tobias at silverxnet dot de
9 years ago
Regarding the previous posting:
I just wanted to give an explanation. This should be because the float to string / integer to string conversion (you are using a string, multiplying it with a float value what php automatically causes to convert the string to a float value). This is a general "problem" (or not), but not that hard to explain.
Where an integer or float starts with 0, in a string it does obviously with 1. So if you are using a string your value will increase by one (You started with a string, so it does not increase but contain the real result. If you start using a float value by not using '' around the value, you have to output the float value as well. This is just the PHP conversion.)

Try putting
$x = strval( $x );
after
$x = $x * 100;
and using your example again. You will see that the output will change to 13664 = 13664 because of the general string conversion. It seems that PHP is converting a float to a string by inceasing by one. By doing the same with intval instead of strval the output changes to 13663 = 13663.

! sprintf seems to behave wrong when using the conversation to an integer value and NOT doing the conversation at all. So use intval to convert to an integer value or strval to convert to a string value BEFORE using sprintf. This should be solving the problems.
up
0
kekec at kukac dot hu
9 years ago
A really working one:
<?php
function cutzero($value) {
   return
preg_replace("/(\.?)0+$/", "", $value);
}
?>
up
0
abiltcliffe at bigfoot.com
10 years ago
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).
up
0
cv at corbach dot de
11 years ago
To make radu.rendec@ines.ro's excellent function work on signed numbers you must change the first line to:

$e = floor(log10(abs($x)));
up
0
prolixmp3 at navigators dot lv
12 years ago
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:

$txt = "Abracadabra"; // actual string
$fit = 16; // how many digits to use
$fill = "."; // what to fill
$digits = sprintf ("%'{$fill}{$fit}s", $txt);

Paul (a.k.a. Mr.Prolix)
up
0
voudras at nospam dot swiftslayer dot org
12 years ago
Little note about sprintf and its ilk.
if you attempt something like
$string = "dingy%sflem%dwombat";
$nbr = 5;
$name = "voudras";

$msg = sprintf("%d $string %s", $nbr, $name);

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
up
-1
carmageddon at gmail dot com
2 years ago
If you want to convert a decimal (integer) number into constant length binary number in lets say 9 bits, use this:

$binary = sprintf('%08b', $number );

for example:
<?php
$bin
= sprintf('%08b',511 );
echo
$bin."\n";
?>

would output 111111111
And 2 would output 00000010

I know the leading zeros are useful to me, perhaps they are to someone else too.
up
-1
savannah at seznam dot cz
4 years ago
If you have problems using utf-8 with string paddings, you can use this function:

<?php
/**
 * Formats string using sprintf, but correctly handles %s  with space paddings
 *
 * uses conversion to iso-8859-2 and back
 *
 * it is, however, much slower, so use only when needed!
 *
 * @param string $format
 */
function utf_8_sprintf ($format) {
 
$args = func_get_args();

  for (
$i = 1; $i < count($args); $i++) {
   
$args [$i] = iconv('UTF-8', 'ISO-8859-2', $args [$i]);
  }
 
  return
iconv('ISO-8859-2', 'UTF-8', call_user_func_array('sprintf', $args));
}

// test

echo sprintf ("[%-20s]\n", 'escrzyaie'); //  how it should look without special chars
echo sprintf ("[%-20s]\n", 'ěščřžýáíé'); // not correctly handled by php
echo utf_8_sprintf ("[%-20s]\n", 'ěščřžýáíé'); // using above function

/*
produces:
[escrzyaie           ]
[ěščřžýáíé  ]
[ěščřžýáíé           ]
*/

?>
the trick is to convert arguments to iso8859-2 and result back to utf-8.
up
-1
andyhaslam at hotmail dot com
5 years ago
An interesting bug, if you do the following:

$val = 2345.35;
$val = sprintf("%01.2f", $val);
echo $val;

Output is "2.00", instead of "2345.35". The solution is to use an intermediate variable:

$val = 2345.35;
$val2 = sprintf("%01.2f", $val);
$val = $val2;
echo $val;
up
-1
Anonymous
6 years ago
In response to juan at ecogomera dot com:

I think what you want is:

$x = 3327
$y=decbin($x);
echo $y."<br>";
$z = sprintf("%012d", $x);
echo $z;

3327
110011111111
000000003327

Right? You were double-converting the number. First to binary, then again to decimal. You should be converting the source number directly into the required base.
up
-1
Fredrik Rambris in the com top domain
6 years ago
The C implementation of printf (alteast in glibc) can handle field length as arguments like this:

printf("[%-*s]\n", (int)20, "Hello");

To have the same result in PHP you need to run

printf("[%s]\n, str_pad("Hello", 20) );

It would be nice if one could use the field length directly like in C.
up
-1
egingell at sisna dot com
7 years ago
<?
/**
 * [string or int] vprint ( string $format [, mixed $ary [, bool $return]] )
 *
 * Closely mimics the functionality of sprintf(), printf(), vprintf(), and vsprintf().
 *
 * Replaces %[bcdeufFosxX] with each element of $ary
 *     See http://us3.php.net/manual/en/function.sprintf.php for details on replacement types.
 *
 * If there are not enough elements in $ary (or it is left out) to satisfy $format,
 *     it will be padded to the correct length.
 *
 * Since v*printf() doesn't mind having too many elements in the array, $format will be left alone.
 *
 * If $ary is a string, it will be recast into an array.
 *
 * If $return is set to a value considered to be false (0, '', null, false, and array()),
 *     then the output will be sent to STDOUT and the strlen() of the output string will be returned;
 *     otherwise, the output string will be returned.
 *
 * It's buggy when using the argument swapping functionality, unless you do it propperly.
 *
 * May break when using modifiers (%.4e, %02s, etc), unless you do it propperly.
 **/
function vprint($format, $ary = array(), $return = true) {
   
// Sanity?!
   
if (!is_array($ary)) $ary = array($ary);

   
// Find %n$n.
   
preg_match_all('#\\%[\\d]*\\$[bcdeufFosxX]#', $format, $matches);

   
// Weed out the dupes and count how many there are.
   
$counts = count(array_unique($matches[0]));

   
// Count the number of %n's and add it to the number of %n$n's.
   
$countf = preg_match_all('#\\%[bcdeufFosxX]#', $format, $matches) + $counts;

   
// Count the number of replacements.
   
$counta = count($ary);

    if (
$countf > $counta) {
       
// Pad $ary if there's not enough elements.
       
$ary = array_pad($ary, $countf, "&nbsp;");
    }

    if (
$return) {
        return
vsprintf($format, $ary);
    } else {
        return
vprintf($format, $ary);
    }
}

?>
up
-1
henke dot andersson at comhem dot se
8 years ago
Mind that it doesn't allow you to use a array as multiple arguments like this:
<?php
printf
('%s %s',array('a','b')) ?>
up
-1
timo at frenay dot net
8 years ago
Note that the documentation is unclear about the details of the sign specifier. First of all, the character for this is "+".

Also note that the following does NOT print "+00.00" as you might expect:

<?php
    printf
('%+02.2f', 0);
?>

The sign is included in the width. This can't be solved by increasing the width:

<?php
    printf
('%+03.2f', 0);
?>

This will put the padding 0 before the sign.
Here is a possible solution:

<?php
    $value
= 0;
   
printf('%s%02.2f', ($value < 0) ? '-' : '+', abs($value));
?>
up
-1
Anonymous
9 years ago
both of your cut-zero functions are just way too complicated. if it's a string where only the zeros at the end should be truncated, why not use a syntax as simple as rtrim("4.7000","0") ?
up
-1
Rene dot Leonhardt at agritec24 dot com
10 years ago
Your cutzero function could be faster ;-)
   return (double)$value;

But if you must have a function:
   return preg_replace('/0+$/', '', $value);
up
-1
fuchschr at surfeu dot at
11 years ago
To have a string with leading zeros use this:
$string_i = sprintf("%04s",$value)

Gives you an output with leading zeros and 4 digits.
i.e.
0001
0002
...
0010
an so on
up
-1
anqmb(at)yahoo.co.jp
11 years ago
Watch out the mysterious rounding rule.
<?php
$a
= 4.5;
$b = sprintf("%d",$a);
$c = 4.5;
$d = sprintf("%.0f",$c);
$e = 0.45;
$f = sprintf("%.1f",$e);
print (
"$b,$d,$f\n");
?>

The code above prints "4,5,0.5".
(Perl version prints "4,4,0.5".)
up
-2
andrejsstepanovs at gmail dot com
2 years ago
Use this function to ignore warning "Too few arguments".

<?php
/**
 * Ignores php E_WARNING "sprintf(): Too few arguments".
 * If parameters is too fiew, then this function add extra empty parameter and try again.
 * Working in recursion.
 *
 * @param string $template
 * @param mixed $parameters
 * @return string
 */
function my_sprintf($template, $parameters){
   if(!
function_exists('handleError')){//initialize new error handler function
     
function handleError($errno, $errstr, $errfile, $errline, array $errcontext){
         throw new
ErrorException($errstr, 0, $errno, $errfile, $errline);
      }
     
set_error_handler('handleError');
   }

   if(!
is_array($parameters)){//manage parameters to allow string
     
$parameters = array($parameters);
   }

   try{
//trying to execute function. if warning is received, then add parameter
     
eval('$return = sprintf($template, "'.implode('","', $parameters).'");');
      return
$return;
   }catch(
ErrorException $e){
     
array_push($parameters, null);
      return
my_sprintf($template, $parameters);
   }
}
?>
up
-2
Ulf Wostner
6 years ago
<?php
#-----------------------------------------------------
# Viewing Two's Complement using sprintf formatting.
#-----------------------------------------------------
# Systems using Two's Complements have exactly one number that equals its own Two's Complement.
# On a 32-bit system look at  1000 0000 0000 0000  for  -2147483648
# Take the one's complement, to get 0111 1111 1111 1111, add 1
# to get the Two's Complement: 1000 0000 0000 0000
#  We are back to the original number, the so-called Weird Number for 32-bits.

# For a 64-bit system, format that number as binary, width 64, padded with 0's.

printf("%064b\n", -2147483648);

# Output with added spaces:
# 11111111 11111111 11111111 11111111 10000000 00000000 00000000 00000000

# And here is the Two's Complement on a 64-bit system.

printf("%064b\n", +2147483648);

# Output with added spaces:
# 00000000 00000000 00000000 00000000 10000000 00000000 00000000 00000000
# They share those last 32 bits, accounting for the 32-bit Weird Number.

#----------------------------------------------------------
# Is PHP running  32-bit or 64-bit?
#----------------------------------------------------------
# Sure, we can look at the max int, but  The Weird Number  also tells if we are in 32-bit, 64-bit, or ...

function getBitCount() {
 
$how_many_bits = 1$n = 2;
  while(
True) {
   
$how_many_bits += 1;   $n *= 2# powers of 2
    # matches its own two's complement? 
   
if( sprintf("%b", $n) == sprintf("%b", -$n)  )
      return
1 + $how_many_bits;
  }
  return;
}
?>
up
-2
ian dot w dot davis at gmail dot com
7 years ago
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.
up
-2
moritz dot geselle at invision-team dot de
10 years ago
a little note to the argument swapping examples which took me a while to get:
if you use single quotes for the format string (like you should do, since there aren't any variable conversions to do as long as you don't need any special chars), the given examples won't work because of the backslash before the $ (needs to be escaped in double quoted strings - but not in single quoted!)

so this:

$format = "The %2\$s contains %1\$d monkeys";
printf($format,$num,$location);

with a single quoted format string would look like this:

$format = 'The %2$s contains %1$d monkeys';
printf($format,$num,$location);

(no escapes)

I hope that helps to avoid confusion ;)
up
-2
eden_zero_x at hotmail dot com
10 years ago
Well I came up with this one, extremely simple. instead of writing <span class="class">hello</a>
you can write: print class('class','hello'); using sprintf
-----------------------------
function class_ ($class, $text=false)
 {
    return sprintf ("<span class=\"%s\">%s</span>",
        $class,
        ($text ? $text : $class)
    );
 }
-----------------------------
up
-3
eagle at electric-force dot net
6 years ago
Display an binary string like an Hex Editor.

<?php
function BinToHexView($binstr) {
   
$HexView = "";

   
$binpos = 0;
   
$binsize = strlen($binstr);
   
$binr = ( ($binsize-$binpos-16) > 16 ? 16 : $binsize-$binpos-16 );

    while (
$binr > 0) {
       
$hline = "";
       
$dline = "";
       
$HexView .= sprintf("%04x", $binpos);
        for (
$c=0;$c<$binr;$c++) {
           
$hline .= sprintf("%02x",ord($binstr[$binpos+$c]))." ";
        }
        for (
$c=0;$c<$binr;$c++) {
           
$ord = ord($binstr[$binpos+$c]);
           
$dline .= ( $ord<32 || $ord>126 ? "." : $binstr[$binpos+$c] );
        }
       
$HexView .= sprintf("  %-48s  %-16s\n", $hline, $dline);
       
$binpos += $binr;
       
$binr = ( ($binsize-$binpos-16) > 16 ? 16 : $binsize-$binpos-16 );
    }

    return
$HexView;
}
?>

 
show source | credits | sitemap | contact | advertising | mirror sites