sprintf格式
sprintf格式
Ruby的sprintf格式與C語言的sprintf(3)基本相同。但還是有些差別: 它沒有針對C特有類型的修飾符,如short或long等; 它包含2進位數的指示符(%b); 它不支援sprintf的方言式的文法。
下面就對ruby的sprintf格式進行詳細的說明。
sprintf格式的規格如下所示。[]中的部分是可選的。
%[指定參數$][標識符][寬度][.精度]指示符
若想輸出`%'本身時, 請這樣`%%'處理。
下面就分別介紹一下各元素的用法。
標識符
標識符包括`#', `+', ` '(空格), `-'和`0'這5個。
-
#
-
使用2進位、8進位、16進位的指示符(`b', `o', `x', `X')時, 會分別添加"0b", "0", "0x", "0X"首碼。
p sprintf("%#b", 10) # => "0b1010"
p sprintf("%#o", 10) # => "012"
p sprintf("%#x", 10) # => "0xa"
p sprintf("%#X", 10) # => "0XA"
對於浮點數 (`f', `e', `E', `g', `G'), 則必定在輸出中添加"."。
p sprintf("%.0f", 10) # => "10"
p sprintf("%#.0f", 10) # => "10."
p sprintf("%.0e", 10) # => "1e+01"
p sprintf("%#.0e", 10) # => "1.e+01"
`g', `G'除了具有上述特性外, 還會在末尾添加多餘的0。
p sprintf("%.05g", 10) # => "10"
p sprintf("%#.05g", 10) # => "10.000"
-
+
-
使輸出字串帶上符號。如果是正數的話, 就會添加`+'。它只對數值指示符(`d', `i', `b', `o', `x', `X', `u', `f', `e', `E', `g', `G')起作用。另外, 如果是`b', `o', `x', `X', `u'的話, 則會為負數添加`-'。
p sprintf("%d", 1) # => "1"
p sprintf("%+d", 1) # => "+1"
p sprintf("%x", -1) # => "..f" # ".." 表示f無限延續
p sprintf("%+x", -1) # => "-1"
-
' '(空格)
-
與`+'相同, 用空格來代替正號`+'。它只對數值指示符(`d', `i', `b', `o', `x', `X', `u', `f', `e', `E', `g', `G')起作用。
p sprintf("%d", 1) # => "1"
p sprintf("%+d", 1) # => "+1"
p sprintf("% d", 1) # => " 1"
p sprintf("%x", -1) # => "..f"
p sprintf("% x", 1) # => " 1"
p sprintf("% x", -1) # => "-1"
-
-
-
使輸出內容靠左. 若尚未指定寬度的話,則不起作用。
-
0
-
當輸出內容靠右時, 使用`0'而並非空格來填充多餘部分。
它只對數值指示符(`d', `i', `b', `o', `x', `X', `u', `f', `g', `G')起作用(對`e', `E'無效)
p sprintf("%010d", 10)
# => "0000000010"
與`#'一起使用時, 輸出情況如下。
p sprintf("%#010x", 10) # => "0x0000000a"
p sprintf("%#010o", 10) # => "0000000012"
p sprintf("%#010b", 10) # => "0b00001010"
它等同於下例。
p sprintf("%#10.8x", 10) # => "0x0000000a"
p sprintf("%#10.9o", 10) # => "0000000012"
p sprintf("%#10.8b", 10) # => "0b00001010"
通常情況下, 會輸出如下內容。
p sprintf("%#10x", 10) # => " 0xa"
p sprintf("%#10o", 10) # => " 012"
p sprintf("%#10b", 10) # => " 0b1010"
寬度
以非0數字開頭的數串負責指定寬度。寬度是指產生字串的寬度, 它不受後文中的精度的限制。
確定寬度時, 也會考慮標識符中附加的" ", "+","-", "0b", "0", "0x", "0X"的長度。
p sprintf("%#05x", 10) # => "0x00a"
寬度是指"必要的最小寬度". 若結果字串的寬度超過指定寬度時, 指定寬度就會失效。
若將寬度指定為`*'時, 將從參數中取得寬度值。
p sprintf("%10s", "foo") # => " foo"
p sprintf("%*s", 10, "foo") # => " foo"
精度
緊跟在"."後面的數串表示精度(若只有"."的話,則為".0")。若遇到整數的指示符(`d', `i', `b', `o', `x', `X', `u')的話,精度表示數值部分的長度。
p sprintf("%10.5d", 1) # => " 00001"
p sprintf("%#10.5x", 1) # => " 0x00001"
p sprintf("%+10.5x", 1) # => " +00001"
若遇到浮點數的指示符(`f')的話,它表示小數部分的位元。
p sprintf("%10.5f", 1) # => " 1.00000"
p sprintf("%10.5f", 10) # => " 10.00000"
若遇到浮點數的指示符(`e', `E', `g', `G')的話,它表示有效位元。
p sprintf("%10.5e", 1) # => "1.00000e+00"
p sprintf("%10.5e", 10) # => "1.00000e+01"
p sprintf("%10.5g", 10) # => " 10"
p sprintf("%#10.5G", 10) # => " 10.000"
如果是字串指示符(`s', `p')的話,將會按照精度的規定來檢查參數中的字串長度,並切除多餘部分。若將寬度和精度設為同值的話,則只輸出參數字串中的符合精度規定的部分。
p sprintf("%10.2s", "foo") # => " fo"
p sprintf("%5.5s", "foo") # => # => " foo"
p sprintf("%5.5s", "foobar") # => # => "fooba"
若將精度設為`*'的話,將從參數中提取精度的值。
p sprintf("%.5s", "foobar") # => "fooba"
p sprintf("%.*s", 5, "foobar") # => "fooba"
指示符
指示符指出參數的類型,且是必選的。大體說來它包括:
- 表示字串的指示符: `c', `s', `p'
- 表示整數的指示符: `d', `i', `u', `b', `o', `x', `X',
- 表示浮點數的指示符: `f', `g', `e', `E', `G'
這幾類。
-
c
-
將參數的數值(0×255)看作是字元代碼,並輸出對應的字元。若參數並非數值、String、 nil, true或false的話,將嘗試用to_int方法進行變換。
此時,只有標識符`-'和"寬度"的設定是有效。
-
s
-
輸出字串。
若參數並非String對象的話,將使用to_s方法對其進行變換。
-
p
-
ruby 1.8 特性: 輸出Object#inspect的結果。
p sprintf("%s", [1, 2, 3]) # => "123"
p sprintf("%p", [1, 2, 3]) # => "[1, 2, 3]"
-
d
-
i
-
以10進位整數的形式輸出參數中的數值。
若參數並非整數,則使用與Integer函數相同的規則將其變為整數。
-
u
-
將參數的數值看作是不帶正負號的整數,並以10進位整數的形式輸出它。
p sprintf("%u", -1) # => "..4294967295"
上面的代碼會輸出 p ".." + 0xffff_ffff.to_s。
ruby 1.7 特性: 在version 1.7中,不會附加".."。若是'%u'的話,則將參數看作是定長整數。此時,對於負整數n來說
printf("%u", n)
與
printf("%d", n & ~(-1 << n.size*8))
是一個意思。
-
b
-
o
-
x
-
X
-
分別以2進位、8進位、16進位、16進位(大寫字母)字串的形式輸出整數。
若使用了`#' 標識符的話,則分別在前面添加"0b", "0", "0x", "0X"。
若沒有使用`+', ` ' 標識符時,將在負數的前面(若有`#' 標識符,則在"0x"等的後面)添加".."。這表示最高位字元無限延伸,它採用了2的補數形式來表現負數。
p sprintf("%#b", 10) # => "0b1010"
p sprintf("%#o", 10) # => "012"
p sprintf("%#x", 10) # => "0xa"
# 對負數添加".."
p sprintf("%#b", -1) # => "0b..1"
p sprintf("%#o", -1) # => "0..7"
p sprintf("%#x", -1) # => "0x..f"
p sprintf("%10x", -1) # => " ..f"
p sprintf("%-10x", -1) # => "..f "
# 若指定了"精度"的話,則不會添加".."
p sprintf("%.10x", -1) # => "ffffffffff"
-
f
-
e
-
E
-
g
-
G
-
`f' 以小數點形式(xxx.xxx)輸出數值。
`e' 以指數形式(x.xxxe+xx)輸出數值。
`g' 的情況比較特殊。當指數小於-4或者超出精度範圍時,它採用`e'方式進行輸出。除此之外,它採用`f'方式進行輸出。另外,它會刪除小數部分尾部的0。
大寫字母指示符(`E', `G')會將輸出中的字母變為大寫形式。
p sprintf("%f", 1.0) # => "1.000000"
p sprintf("%e", 1.0) # => "1.000000e+00"
p sprintf("%g", 1.0) # => "1"
p sprintf("%f", 10.1) # => "10.100000"
p sprintf("%e", 10.1) # => "1.010000e+01"
p sprintf("%g", 10.1) # => "10.1"
p sprintf("%g", 10 ** 6) # => "1e+06"
p sprintf("%g", 10 ** -5) # => "1e-05"
精度的預設值為6。
若遇到無限大值或NaN(Not a Number)時,輸出情況如下。
p sprintf("%f", 1.0/0) # => "inf"
p sprintf("%f", -1.0/0) # => "-inf"
p sprintf("%f", 0.0/0) # => "nan"
p sprintf("%E", 1.0/0) # => "INF"
p sprintf("%E", -1.0/0) # => "-INF"
p sprintf("%E", 0.0/0) # => "NAN"
指定參數
這部分的利用頻率最低,所以放在最後。
-
nth$
-
表示將使用第nth個參數進行格式化操作。
p sprintf("%1$d, %1$x, %1$o", 10)
=> "10, a, 12"
p sprintf("%3$d, %2$x, %1$o", 1, 2, 3)
=> "3, 2, 1"
若您不想改變參數的順序而只想改變格式的話,也可以使用它。
case ENV['LC_TIME']
when /^ja_JP/
fmt = "%1$d年%2$d月%3$d日"
else
fmt = "%2$02d/%03$2d/%1$02d"
end
p sprintf(fmt, 1, 4, 22)
=> "04/22/01"
您也可以先插入"*",然後借用參數來設定"寬度"和"精度"的值。
p sprintf("%5.2f", 1); # => " 1.00"
p sprintf("%*.*f", 5, 2, 1); # => " 1.00"
p sprintf("%1$*2$.*3$f", 1, 5, 2); # => " 1.00