sprintf Format

The sprintf format of Ruby is basically the same as that in C. However, there are some differences, such as no short or long modifier as in C, there is a 2-bit variable indicator (%b), and not all of the dialects of sprintf (': 3-digit separators) are supported.

A complete explanation of Ruby's sprintf format is provided below.

Below is a sprintf format form. The parts enclosed in [ ] can be omitted.

%[flag][width][.accuracy]indicator

To output '%' type '%%'.

Below is an explanation of each of the elements.

Flag

There are 5 types of flags: '#', '+', ' ' (space), '-', '0'

#

With the binary, octal, and hexadecimal indicators ('b', 'o', 'x', 'X'), "0b", "0", "0x" and "0X" are added as prefixes.

p sprintf("%#b", 10) # => "0b1010"
p sprintf("%#o", 10) # => "012"
p sprintf("%#x", 10) # => "0xa"
p sprintf("%#X", 10) # => "0XA"

For floating-point numbers ('f', 'e', 'E', 'g' and 'G') always put a "." in the output.

p sprintf("%.0f", 10) # => "10"
p sprintf("%#.0f", 10) # => "10."
p sprintf("%.0e", 10) # => "1e+01"
p sprintf("%#.0e", 10) # => "1.e+01"

For 'g', 'G', there is a leftover 0 on the end in addition to the above.

p sprintf("%.05g", 10) # => "10"
p sprintf("%#.05g", 10) # => "10.000"
+

Symbols will be attached to output character strings. In particular, a '+' symbol will be added to positive numbers. This only applies to the following numerical value indicators: 'd', 'i', 'b', 'o', 'x', 'X', 'u', 'f', 'e', 'E', 'g' and 'G'. Also, for 'b', 'o', 'x', 'X', and 'u', a '-' symbol will be added to negative numbers.

p sprintf("%d", 1)   # => "1"
p sprintf("%+d", 1)  # => "+1"

p sprintf("%x", -1)  # => "..f"  # ".." shows that f continues infinitely
p sprintf("%+x", -1) # => "-1"
' ' (space)

Same meaning as a '+' symbol, but here, a space is used in place of the '+' symbol, meaning positive. This only applies to the following numerical value indicators: '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"
-

Output is left justified. It only has meaning if "Width" is specified.

0

If output is right justified, '0' will fill in the leftover sections in place of a blank space.

This only applies to the following numerical value indicators: 'd', 'i', 'b', 'o', 'x', 'X', 'u', 'f', 'g', 'G' (It does not apply to 'e' or 'E').

p sprintf("%010d", 10)
# => "0000000010"

Output specified together with '#' is shown below.

p sprintf("%#010x", 10)  # => "0x0000000a"
p sprintf("%#010o", 10)  # => "0000000012"
p sprintf("%#010b", 10)  # => "0b00001010"

This is the same as below.

p sprintf("%#10.8x", 10) # => "0x0000000a"
p sprintf("%#10.9o", 10) # => "0000000012"
p sprintf("%#10.8b", 10) # => "0b00001010"

Normally shown as displayed below.

p sprintf("%#10x", 10)   # => "       0xa"
p sprintf("%#10o", 10)   # => "       012"
p sprintf("%#10b", 10)   # => "    0b1010"

Width

A number string that begins with any number other than 0 is the specified width. Width displays the length of the character string produced. Contrary to the value of "Precision", which is mentioned later, only the number string of the width part is produced.

As for width specification, the length of " ", "+", "-", "0b", "0", "0x", "0X", which are presented as "Flags", is also considered.

p sprintf("%#05x", 10) # => "0x00a"

Width is a specification of the "minimum necessary width." If the resulting number string goes over the specified width, width specification is no longer valid.

If width is specified as '*', then the width value is received from an argument.

p sprintf("%10s", "foo")    # => "       foo"
p sprintf("%*s", 10, "foo") # => "       foo"

Precision

A number string that follows a "." indicates the precision (when only a "." is displayed, it is the same as ".0"). Precision means the length of a portion of numerical value strings for the following integer indicators: '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"

This means the decimal places for the floating-point indicator 'f'.

p sprintf("%10.5f", 1)   # => "   1.00000"
p sprintf("%10.5f", 10)  # => "  10.00000"

This means the number of significant digits for floating-point indicators 'e', 'E', 'g', and '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"

For character string indicators 's' and 'p', the portion which goes over the specified number within the argument character string is truncated. If width and precision values are the same, only the output for that length will be performed, no matter what the argument is.

p sprintf("%10.2s", "foo")  # => "        fo"

p sprintf("%5.5s", "foo")     # => # => "  foo"
p sprintf("%5.5s", "foobar")  # => # => "fooba"

If '*' is specified as precision, the precision value will be obtained from the argument.

p sprintf("%.5s", "foobar")    # => "fooba"
p sprintf("%.*s", 5, "foobar") # => "fooba"

Indicators

Indicators show argument pattern interpretations. They cannot be abbreviated and are divided into the following groups:

c

Argument values 0-255 are regarded as character codes, then the corresponding characters are output. Argument conversion is attempted with the to_int method for objects other than numerical values, String, nil, true, and false.

This only applies to flag '-' and "width" specification.

s

Character strings are output.

If the argument is not a String object, the to_s method causes the object turned into a character string to be treated as an argument.

p

Object#inspect results are output.

p sprintf("%s", [1, 2, 3])      # => "123"
p sprintf("%p", [1, 2, 3])      # => "[1, 2, 3]"
d
i

An argument's numerical value is output as an integer decimal expression.

If the argument is not an integer, it will be converted to one.

u

The argument value is regarded as an unsigned integer and then output as a decimal integer.

p sprintf("%u", -1) # => "4294967295"

The above code outputs p 0xffff_ffff.to_s.

'%u' regards the argument as a fixed length integer, and

printf("%u", n)

has the same meaning as

printf("%d", n & ~(-1 << n.size*8))

for negative integer n.

b
o
x
X

Integers are output as character strings with binary, octal, hexadecimal, and hexadecimal (uppercase letters) expressions.

If the '#' flag is specified, "0b", "0", "0x", "0X" are added to the front.

If the '+' or ' ' flags are not used, ".." (if the '#' flag is used, after "0x" etc.) is added to the front of negative numbers. This means that characters of the highest-order digit continue infinitely, and negative numbers are shown in complementary numbers of 2.

p sprintf("%#b", 10)    # => "0b1010"
p sprintf("%#o", 10)    # => "012"
p sprintf("%#x", 10)    # => "0xa"

# ".." is added to # negative numbers
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       "

# If "precision" has been specified, ".." is not added.
p sprintf("%.10x", -1)  # => "ffffffffff"
f
e
E
g
G

'f' outputs numerical values with a decimal expression (xxx.xxx).

'e' outputs numerical values with an exponential notation (x.xxxe+xx).

When the exponent is smaller then -4, or higher than the precision, 'g' outputs the same as 'e'. In all other cases, it outputs the same as 'f'. However, 0 at the end of a decimal fraction is omitted.

Uppercase indicators 'E' and 'G' change the output alphabetic characters into uppercase letters.

p sprintf("%f", 1.0) # => "1.000000"
p sprintf("%e", 1.0) # => "1.000000e+000"
p sprintf("%g", 1.0) # => "1"

p sprintf("%f", 10.1) # => "10.100000"
p sprintf("%e", 10.1) # => "1.010000e+001"
p sprintf("%g", 10.1) # => "10.1"

p sprintf("%g", 10 ** 6)  # => "1e+006"
p sprintf("%g", 10 ** -5) # => "1e-005"

The precision default value is 6.

Argument Specification

This is not used often, so it is explained last.

nth$

Indicates that formatting of the nth argument will be performed.

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"

Used when you want to change the format according to the situation, but you do not want to change the order of the arguments.

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"