傳回一個字串,其格式化方式遵循 C 函式庫函數 sprintf
的慣例 printf
。有關更多詳細資料,請參閱下方內容,並參閱系統上的 sprintf(3) 或 printf(3),以了解一般原則的說明。
例如
# Format number with up to 8 leading zeroes
my $result = sprintf("%08d", $number);
# Round number to 3 digits after decimal point
my $rounded = sprintf("%.3f", $number);
Perl 執行自己的 sprintf
格式化:它模擬 C 函數 sprintf(3),但除了浮點數以外,不會使用它,而且即使如此,也只允許使用標準修改器。因此,Perl 無法使用您所在 sprintf(3) 中的非標準擴充功能。
與 printf
不同,當您將陣列作為第一個引數傳遞給 sprintf
時,它不會執行您可能預期的動作。陣列會給予標量內容,而 Perl 也不會將陣列的第 0 個元素用作格式,而是會將陣列中的元素數量用作格式,這幾乎沒有用處。
Perl 的 sprintf
允許下列眾所周知的轉換
%% a percent sign
%c a character with the given number
%s a string
%d a signed integer, in decimal
%u an unsigned integer, in decimal
%o an unsigned integer, in octal
%x an unsigned integer, in hexadecimal
%e a floating-point number, in scientific notation
%f a floating-point number, in fixed decimal notation
%g a floating-point number, in %e or %f notation
此外,Perl 允許下列廣泛支援的轉換
%X like %x, but using upper-case letters
%E like %e, but using an upper-case "E"
%G like %g, but with an upper-case "E" (if applicable)
%b an unsigned integer, in binary
%B like %b, but using an upper-case "B" with the # flag
%p a pointer (outputs the Perl value's address in hexadecimal)
%n special: *stores* the number of characters output so far
into the next argument in the parameter list
%a hexadecimal floating point
%A like %a, but using upper-case letters
最後,為了向後(我們確實是指「向後」)相容性,Perl 允許這些不必要的但廣泛支援的轉換
%i a synonym for %d
%D a synonym for %ld
%U a synonym for %lu
%O a synonym for %lo
%F a synonym for %f
請注意,對於指數模數小於 100 的數字,%e
、%E
、%g
和 %G
產生的科學記號中指數數字的數量取決於系統:它可能是三個或更少(視需要以零填充)。換句話說,1.23 乘以 10 的 99 次方可能是「1.23e99」或「1.23e099」。%a
和 %A
也類似:指數或十六進位數字可能會浮動:特別是 Perl 組態選項「long doubles」可能會造成驚喜。
在 %
和格式字母之間,您可以指定幾個額外的屬性來控制格式的詮釋。依序為
明確的格式參數索引,例如 2$
。預設情況下,sprintf 會格式化清單中下一個未使用的引數,但這允許您按順序取出引數
printf '%2$d %1$d', 12, 34; # prints "34 12"
printf '%3$d %d %1$d', 1, 2, 3; # prints "3 1 1"
一個或多個
space prefix non-negative number with a space
+ prefix non-negative number with a plus sign
- left-justify within the field
0 use zeros, not spaces, to right-justify
# ensure the leading "0" for any octal,
prefix non-zero hexadecimal with "0x" or "0X",
prefix non-zero binary with "0b" or "0B"
例如
printf '<% d>', 12; # prints "< 12>"
printf '<% d>', 0; # prints "< 0>"
printf '<% d>', -12; # prints "<-12>"
printf '<%+d>', 12; # prints "<+12>"
printf '<%+d>', 0; # prints "<+0>"
printf '<%+d>', -12; # prints "<-12>"
printf '<%6s>', 12; # prints "< 12>"
printf '<%-6s>', 12; # prints "<12 >"
printf '<%06s>', 12; # prints "<000012>"
printf '<%#o>', 12; # prints "<014>"
printf '<%#x>', 12; # prints "<0xc>"
printf '<%#X>', 12; # prints "<0XC>"
printf '<%#b>', 12; # prints "<0b1100>"
printf '<%#B>', 12; # prints "<0B1100>"
當空格和加號同時作為旗標時,會忽略空格。
printf '<%+ d>', 12; # prints "<+12>"
printf '<% +d>', 12; # prints "<+12>"
當在 %o 轉換中給定 # 旗標和精度時,如果前導「0」需要,精度會增加。
printf '<%#.5o>', 012; # prints "<00012>"
printf '<%#.5o>', 012345; # prints "<012345>"
printf '<%#.0o>', 0; # prints "<0>"
此旗標告訴 Perl 將提供的字串詮釋為整數向量,字串中每個字元一個。Perl 依序將格式套用至每個整數,然後以分隔符號(預設為點 .
)將結果字串串接。這對於顯示任意字串中字元的序數值很有用
printf "%vd", "AB\x{100}"; # prints "65.66.256"
printf "version is v%vd\n", $^V; # Perl's version
在 v
之前加上星號 *
以覆寫用於分隔數字的字串
printf "address is %*vX\n", ":", $addr; # IPv6 address
printf "bits are %0*v8b\n", " ", $bits; # random bitstring
您也可以明確指定要使用的引數編號來串接字串,例如使用 *2$v
;例如
printf '%*4$vX %*4$vX %*4$vX', # 3 IPv6 addresses
@addr[1..3], ":";
引數通常會格式化為僅與顯示給定值一樣寬。您可以透過在此處放置數字來覆寫寬度,或從下一個引數(使用 *
)或從指定的引數(例如,使用 *2$
)取得寬度
printf "<%s>", "a"; # prints "<a>"
printf "<%6s>", "a"; # prints "< a>"
printf "<%*s>", 6, "a"; # prints "< a>"
printf '<%*2$s>', "a", 6; # prints "< a>"
printf "<%2s>", "long"; # prints "<long>" (does not truncate)
如果透過 *
取得的欄位寬度為負值,則其效果與 -
旗標相同:靠左對齊。
您可以透過指定一個點 .
後接一個數字來指定精度(對於數字轉換)或最大寬度(對於字串轉換)。對於除了 g
和 G
之外的浮點格式,這會指定小數點右邊要顯示幾個位數(預設為 6)。例如
# these examples are subject to system-specific variation
printf '<%f>', 1; # prints "<1.000000>"
printf '<%.1f>', 1; # prints "<1.0>"
printf '<%.0f>', 1; # prints "<1>"
printf '<%e>', 10; # prints "<1.000000e+01>"
printf '<%.1e>', 10; # prints "<1.0e+01>"
對於「g」和「G」,這會指定要顯示的最大有效數字位數;例如
# These examples are subject to system-specific variation.
printf '<%g>', 1; # prints "<1>"
printf '<%.10g>', 1; # prints "<1>"
printf '<%g>', 100; # prints "<100>"
printf '<%.1g>', 100; # prints "<1e+02>"
printf '<%.2g>', 100.01; # prints "<1e+02>"
printf '<%.5g>', 100.01; # prints "<100.01>"
printf '<%.4g>', 100.01; # prints "<100>"
printf '<%.1g>', 0.0111; # prints "<0.01>"
printf '<%.2g>', 0.0111; # prints "<0.011>"
printf '<%.3g>', 0.0111; # prints "<0.0111>"
對於整數轉換,指定一個精度表示數字本身的輸出應以零填充到此寬度,其中會忽略 0 旗標
printf '<%.6d>', 1; # prints "<000001>"
printf '<%+.6d>', 1; # prints "<+000001>"
printf '<%-10.6d>', 1; # prints "<000001 >"
printf '<%10.6d>', 1; # prints "< 000001>"
printf '<%010.6d>', 1; # prints "< 000001>"
printf '<%+10.6d>', 1; # prints "< +000001>"
printf '<%.6x>', 1; # prints "<000001>"
printf '<%#.6x>', 1; # prints "<0x000001>"
printf '<%-10.6x>', 1; # prints "<000001 >"
printf '<%10.6x>', 1; # prints "< 000001>"
printf '<%010.6x>', 1; # prints "< 000001>"
printf '<%#10.6x>', 1; # prints "< 0x000001>"
對於字串轉換,指定一個精度會將字串截斷以符合指定的寬度
printf '<%.5s>', "truncated"; # prints "<trunc>"
printf '<%10.5s>', "truncated"; # prints "< trunc>"
您也可以使用 .*
從下一個參數取得精度,或從指定的參數取得(例如,使用 .*2$
)
printf '<%.6x>', 1; # prints "<000001>"
printf '<%.*x>', 6, 1; # prints "<000001>"
printf '<%.*2$x>', 1, 6; # prints "<000001>"
printf '<%6.*2$x>', 1, 4; # prints "< 0001>"
如果透過 *
取得的精度為負值,則會視為完全沒有精度。
printf '<%.*s>', 7, "string"; # prints "<string>"
printf '<%.*s>', 3, "string"; # prints "<str>"
printf '<%.*s>', 0, "string"; # prints "<>"
printf '<%.*s>', -1, "string"; # prints "<string>"
printf '<%.*d>', 1, 0; # prints "<0>"
printf '<%.*d>', 0, 0; # prints "<>"
printf '<%.*d>', -1, 0; # prints "<0>"
對於數字轉換,您可以使用 l
、h
、V
、q
、L
或 ll
指定要將數字解譯為的大小。對於整數轉換(d u o x X b i D U O
),數字通常假設為您的平台上的預設整數大小(通常為 32 或 64 位元),但您可以覆寫此設定,改用編譯 Perl 所使用的編譯器支援的標準 C 類型之一
hh interpret integer as C type "char" or "unsigned
char" on Perl 5.14 or later
h interpret integer as C type "short" or
"unsigned short"
j interpret integer as C type "intmax_t" on Perl
5.14 or later; and prior to Perl 5.30, only with
a C99 compiler (unportable)
l interpret integer as C type "long" or
"unsigned long"
q, L, or ll interpret integer as C type "long long",
"unsigned long long", or "quad" (typically
64-bit integers)
t interpret integer as C type "ptrdiff_t" on Perl
5.14 or later
z interpret integer as C types "size_t" or
"ssize_t" on Perl 5.14 or later
請注意,一般來說,從 Perl 程式碼使用 l
修改器(例如,寫入 "%ld"
或 "%lu"
,而不是 "%d"
和 "%u"
)是不必要的。此外,它可能會造成問題,例如在 Windows 64 位元中,長度為 32 位元。
從 5.14 開始,如果這些修改器在您的平台上不受支援,則不會引發例外。但是,如果啟用警告,則會在不受支援的轉換旗標上發出 printf
警告類別的警告。如果您反而偏好例外,請執行下列動作
use warnings FATAL => "printf";
如果您想在開始執行程式之前了解版本相依性,請在其頂端放置類似以下的內容
use v5.14; # for hh/j/t/z/ printf modifiers
您可以透過 Config 找出您的 Perl 是否支援四元數
use Config;
if ($Config{use64bitint} eq "define"
|| $Config{longsize} >= 8) {
print "Nice quads!\n";
}
對於浮點轉換(e f g E F G
),數字通常假設為您的平台上的預設浮點大小(雙精度或長雙精度),但如果您平台支援,您可以使用 q
、L
或 ll
強制使用「長雙精度」。您可以透過 Config 找出您的 Perl 是否支援長雙精度
use Config;
print "long doubles\n" if $Config{d_longdbl} eq "define";
您可以透過 Config 找出 Perl 是否將「長雙精度」視為您的平台上要使用的預設浮點大小
use Config;
if ($Config{uselongdouble} eq "define") {
print "long doubles by default\n";
}
長雙精度和雙精度也可能是同一個東西
use Config;
($Config{doublesize} == $Config{longdblsize}) &&
print "doubles are long doubles\n";
大小指定符 V
對 Perl 程式碼沒有作用,但支援與 XS 程式碼相容。它的意思為「使用 Perl 整數或浮點數的標準大小」,這是預設值。
通常,sprintf
會將下一個未使用的引數當成要格式化的值,以符合每個格式規範。如果格式規範使用 *
來要求額外的引數,這些引數會從引數清單中,以它們在格式規範中出現的順序(在要格式化的值之前)來使用。當引數是由明確的索引所指定時,這不會影響引數的正常順序,即使明確指定的索引會是下一個引數。
因此
printf "<%*.*s>", $a, $b, $c;
使用 $a
作為寬度,$b
作為精度,以及 $c
作為要格式化的值;而
printf '<%*1$.*s>', $a, $b;
會使用 $a
作為寬度和精度,以及 $b
作為要格式化的值。
以下是一些其他範例;請注意,當使用明確的索引時,$
可能需要跳脫
printf "%2\$d %d\n", 12, 34; # will print "34 12\n"
printf "%2\$d %d %d\n", 12, 34; # will print "34 12 34\n"
printf "%3\$d %d %d\n", 12, 34, 56; # will print "56 12 34\n"
printf "%2\$*3\$d %d\n", 12, 34, 3; # will print " 34 12\n"
printf "%*1\$.*f\n", 4, 5, 10; # will print "5.0000\n"
如果 use locale
(包括 use locale ':not_characters'
)生效,且 POSIX::setlocale
已被呼叫,則用於格式化浮點數中的小數分隔符號的字元會受到 LC_NUMERIC
區域設定的影響。請參閱 perllocale 和 POSIX。