php 中的sprintf 坑


先說下為什么要寫這個函數的前言,這個是我在看工作中發現一處四舍五入的bug后,當時非常不理解,

echo sprintf('%.2f',123.455); //123.45
echo sprintf('%.2f',12.455);//12.46

於是查了百度,但是很多結果都很籠統,結果也很少,后來查閱了相關資料總結了下:

基本語法格式:sprintf("%格式化類型","$str1","$str2") ;先別急我會一個個慢慢說

先看一下類型參照表,也就是要轉換成什么類型的格式

%d 十進制有符號整數
%u 十進制無符號整數
%f 浮點數
%s 字符串
%c 單個字符
%p 指針的值
%e 指數形式的浮點數
%x, %X 無符號以十六進制表示的整數
%o 無符號以八進制表示的整數
%g 自動選擇合適的表示法
說明: 

(1). 可以在"%"和字母之間插進數字表示最大場寬。 

例如: %3d 表示輸出3位整型數, 不夠3位右對齊。 

%9.2f 表示輸出場寬為9的浮點數, 其中小數位為2, 整數位為6, 

小數點占一位, 不夠9位右對齊。 

%8s 表示輸出8個字符的字符串, 不夠8個字符右對齊。 

如果字符串的長度、或整型數位數超過說明的場寬, 將按其實際長度輸出。 

但對浮點數, 若整數部分位數超過了說明的整數位寬度, 將按實際整數位輸出; 

若小數部分位數超過了說明的小數位寬度, 則按說明的寬度以四舍五入輸出。 

另外, 若想在輸出值前加一些0, 就應在場寬項前加個0。 (即不夠場寬的用0補足)

例如: %04d 表示在輸出一個小於4位的數值時, 將在前面補0使其總寬度為4位。

如果用浮點數表示字符或整型量的輸出格式, 小數點后的數字代表最大寬度, 小數點前的數字代表最小寬度。

例如: %6.9s 表示顯示一個長度不小於6且不大於9的字符串。若大於9, 則第9個字符以后的內容將被刪除。

(2). 可以在"%"和字母之間加小寫字母l, 表示輸出的是長型數。 

例如: %ld 表示輸出long整數 

%lf 表示輸出double浮點數 

(3). 可以控制輸出左對齊或右對齊, 即在"%"和字母之間加入一個"-" 號可說明輸出為左對齊, 否則為右對齊。 

例如: %-7d 表示輸出7位整數左對齊 

%-10s 表示輸出10個字符左對齊 

2. 一些特殊規定字符

b 字符 作用

\n 換行
\f 清屏並換頁
\r 回車
\t Tab符
\xhh 表示一個ASCII碼用16進表示,
其中hh是1到2個16進制數

舉例幾個簡單的應用

<?php
printf("$%01.2f", 43.2); // 運行結果:$43.20

printf("%d bottles of beer on %s", 100, "the wall");

//運行結果:100 bottles of beer on the wall
printf("%15s", "some text"); //運行結果:some text
?>
<?php
printf("The %2\$s likes to %1\$s",111,  "dog", "bark");
//運行結果: The dog likes to 111
printf("The %1\$s says: %2\$s, %2\$s.", "dog", "bark");
//運行結果:The dog says: bark, bark.
?>
<?php

$var1 = 68.75;
$var2 = 54.35;
$var3 = $var1 + $var2;
echo $var3.'<br>';

// 變量 $var3 值為 "123.1";
$formatted = sprintf ("%01.2f", $var3);

echo $formatted;
// 變量$var3 值為 "123.10"
?>
<?php
$money = 1.4;
$formatted = sprintf ("%-01.2f", $money);
echo $formatted;//1.40
?>

再舉個最簡單的案例

<?php
$str1="1234";

echo sprintf("hello%s","$str1");

//輸出為: hello1234

?>

要點:

%s = %符號和后面屬性符號(s)總稱為插入標記組合,也就是把后面准備進行格式化的值($str1)替換在這個位置 

hello = 這個單詞就是很多人蒙蔽的地方,告訴你這個什么代表也沒有,就單純的代表一個hello,用於分割或者修飾用,一般用[ %s ]、<%s>這樣格式化出來后就直接在標簽里

記住,一個%標記符后面只有一個類型屬性(比如s),s是什么上面有,以字符串的方式格式化

 

那么多個值怎么格式化一起呢

<?php
$a="abcdef";
$b="abcdef";

$c="1234";
echo sprintf("%1\$s%2\$s",$c,$a);

//輸出為: 1234abcdef

?>
%s為一個標記,兩個%s%s這樣寫卻是錯誤的,每個%s必須標記鍵位,不然我怎么知道都代表格式化后面的哪個$str呢,所以有個特別的語法

%1\$%2\$      解釋:%1表示格式化sprintf("%1\$%2\$",''$str1","$str2")中對應的$str1,那么%2自然表示格式化$str2,\$是代表有多個值准備格式化,所以每個%1和%2或者還有%3的標記后都要加這個符號代表一行中有多個標記,如果只有一個標記就不用\$了占位符了,記住$str2、$str3是可選,也就是可以不格式化這么多

再來個特殊的例子

<?php
$a="abcdef";
$b="abcdef";

$c="1234";
echo sprintf("%'a13.2f",$c);

// 輸出為:aaaaaa1234.00

//echo sprintf("%06.2f", $a);

?>

sprintf("%'a13.2f",$c);

這是什么意思,f是浮點數,第一步按照格式 %   '(補位值) 寬度值  格式化類型  這三部分,語法之間必須緊挨着不能用空格

必須解釋一下何為補位值:就是設定的寬度超出了,用這個值來填上

 

解釋一下,補位值只有設置寬度超出了目標值才能用

所以就是用a補位,13為總寬度,2為小數點后的寬度,f為格式化類型,別急我會解釋

 ' 號(單引號)代表接下來要用補位類型

 

為什么他能識別x是補位值呢,因為前面有 ' 號,

為什么他能識別哪幾位是哪種類型呢,他是這樣識別的,按順序從先從兩頭的字符開始識別是什么類型,補位值肯定是單數位,不可能一個位置補兩個數吧,所以左邊第一位x是補位值,右邊第一位是格式化類型,然后中間的自然是寬度值

第二,為什么小數點 后還有一個屬性 ,因為這是f(浮點型),必須設置小數點后有幾位,不能小數后面不能設置了吧,那浮點數意義何在呢

來個整數補位

<?php
$a="abcdef";
$b="abcdef";

$c="1234";
echo sprintf("%'07s",$c);

//結果是:0001234

?>

這就是整數補位,還是一樣
第一步按照格式 %   '(補位值) 寬度值  格式化類型  這三部分

0是補位值 7是寬度值 s自然是格式化類型

還有一種最重要的例子

<?php
$a="abcdef";
$b="abcdef";

$c="1234";
echo sprintf("[%-6s]",$c);       //結果是:[1234 ]

echo sprintf("[%-4s]",$c);       //結果是:[1234]

echo sprintf("[%4.2s]",$c);       //結果是:[ 12]

?>

這個第一步 [ ] 僅僅只是修飾,不用理解

第二步,沒有 ' 號,證明沒有補位,無需添加補位值

所以語法格式為 : %    寬度值  格式化類型  這兩部分

 

第一二行解釋如下:

第一個寬度為6,但是$c=1234 ,只有4個字符,所以寬度不夠,所以右邊自動擴充(擴充再多也只顯示一個空格位置),為什么在右邊擴充,因為寬度前有個 - 號,代表補位方向相反,如在補位值前加-,自然從右邊開始補位

下面為什么沒變化,因為寬度正好一致,只是補位的方向改變了

 

第三行解釋如下:

不要被蒙蔽了,語法結構還是一樣    %    寬度值  格式化類型  這兩部分

沒有 ' 號,證明沒有補位,無需添加補位值

所以4.2依舊是寬度值

只是小數點左邊的4代表總寬度,右邊的2代表只顯示2位出來,所以又空缺了兩個,所以左邊開始擴充兩個空位,為什么只顯示一個空格上一段說了,再說一次吧擴充再多也只顯示一個空格位置。默認從左邊開始

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM