Documentation for sub sprintf

Documentation for sub sprintf, assembled from the following types:

class Str

From Str

(Str) sub sprintf

multi sub sprintfStr:D $format*@args --> Str:D)

This function is mostly identical to the C library sprintf and printf functions. The only difference between the two functions is that sprintf returns a string while the printf function writes to a file.

The $format is scanned for % characters. Any % introduces a format token. Format tokens have the following grammar:

grammar Str::SprintfFormat {
 regex format_token { '%'<index>? <precision>? <modifier>? <directive> }
 token index { \d+ '$' }
 token precision { <flags>? <vector>? <precision_count> }
 token flags { <[ \x20 + 0 \# \- ]>+ }
 token precision_count { [ <[1..9]>\d* | '*' ]? [ '.' [ \d* | '*' ] ]? }
 token vector { '*'? v }
 token modifier { < ll l h V q L > }
 token directive { < % c s d u o x e f g X E G b p n i D U O F > }
}

Directives guide the use (if any) of the arguments. When a directive (other than %) is used, it indicates how the next argument passed is to be formatted into the string to be created.

NOTE: The information below is for a fully functioning sprintf implementation which hasn't been achieved yet. Formats or features not yet implemented are marked NYI.

The directives are:

% a literal percent sign
c a character with the given codepoint
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
X like x, but using uppercase letters
E like e, but using an uppercase "E"
G like g, but with an uppercase "E" (if applicable)
b an unsigned integer, in binary

Compatibility:

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

Perl 5 (non-)compatibility:

n produces a runtime exception
p produces a runtime exception

Modifiers change the meaning of format directives, but are largely no-ops (the semantics are still being determined).

h interpret integer as native "short" (typically int16)
NYI l interpret integer as native "long" (typically int32 or int64)
NYI ll interpret integer as native "long long" (typically int64)
NYI L interpret integer as native "long long" (typically uint64)
NYI q interpret integer as native "quads" (typically int64 or larger)

Between the % and the format letter, you may specify several additional attributes controlling the interpretation of the format. In order, these are:

format parameter index

An explicit format parameter index, such as 2$. By default, sprintf will format the next unused argument in the list, but this allows you to take the arguments out of order:

sprintf '%2$d %1$d'1234;      # OUTPUT: «34 12␤» 
sprintf '%3$d %d %1$d'123;  # OUTPUT: «3 1 1␤» 

flags

One or more of:

space + prefix non-negative number with a space prefix non-negative number with a plus sign
0 use leading zeros, not spaces, for required padding
# ensure the leading "0" for any octal,
prefix non-zero hexadecimal with "0x" or "0X",
prefix non-zero binary with "0b" or "0B"

For example:

sprintf '<% d>',  12;   # OUTPUT: «< 12>␤» 
sprintf '<% d>',   0;   # OUTPUT: «< 0>"» 
sprintf '<% d>'-12;   # OUTPUT: «<-12>␤» 
sprintf '<%+d>',  12;   # OUTPUT: «<+12>␤» 
sprintf '<%+d>',   0;   # OUTPUT: «<+0>"» 
sprintf '<%+d>'-12;   # OUTPUT: «<-12>␤» 
sprintf '<%6s>',  12;   # OUTPUT: «<    12>␤» 
sprintf '<%-6s>'12;   # OUTPUT: «<12    >␤» 
sprintf '<%06s>'12;   # OUTPUT: «<000012>␤» 
sprintf '<%#o>',  12;   # OUTPUT: «<014>␤» 
sprintf '<%#x>',  12;   # OUTPUT: «<0xc>␤» 
sprintf '<%#X>',  12;   # OUTPUT: «<0XC>␤» 
sprintf '<%#b>',  12;   # OUTPUT: «<0b1100>␤» 
sprintf '<%#B>',  12;   # OUTPUT: «<0B1100>␤» 

When a space and a plus sign are given as the flags at once, the space is ignored:

sprintf '<%+ d>'12;   # OUTPUT: «<+12>␤» 
sprintf '<% +d>'12;   # OUTPUT: «<+12>␤» 

When the # flag and a precision are given in the %o conversion, the precision is incremented if it's necessary for the leading "0":

sprintf '<%#.5o>'012;      # OUTPUT: «<000012>␤» 
sprintf '<%#.5o>'012345;   # OUTPUT: «<012345>␤» 
sprintf '<%#.0o>'0;        # OUTPUT: «<>␤» # zero precision results in no output! 

vector flag

This flag tells Perl 6 to interpret the supplied string as a vector of integers, one for each character in the string. Perl 6 applies the format to each integer in turn, then joins the resulting strings with a separator (a dot, '.', by default). This can be useful for displaying ordinal values of characters in arbitrary strings:

  NYI sprintf "%vd""AB\x{100}";           # "65.66.256" 
  NYI sprintf "version is v%vd\n"$^V;     # Perl 6's version 

You can also explicitly specify the argument number to use for the join string using something like *2$v; for example:

  NYI sprintf '%*4$vX %*4$vX %*4$vX',       # 3 IPv6 addresses 
          @addr[1..3], ":";

(minimum) width

Arguments are usually formatted to be only as wide as required to display the given value. You can override the width by putting a number here, or get the width from the next argument (with * ) or from a specified argument (e.g., with *2$):

sprintf "<%s>""a";           # OUTPUT: «<a>␤» 
sprintf "<%6s>""a";          # OUTPUT: «<     a>␤» 
sprintf "<%*s>"6"a";       # OUTPUT: «<     a>␤» 
 NYI sprintf '<%*2$s>'"a"6# "<     a>" 
sprintf "<%2s>""long";       # OUTPUT: «<long>␤» (does not truncate) 

If a field width obtained through * is negative, it has the same effect as the - flag: left-justification.

precision, or maximum width

You can specify a precision (for numeric conversions) or a maximum width (for string conversions) by specifying a . followed by a number. For floating-point formats, except g and G, this specifies how many places right of the decimal point to show (the default being 6). For example:

# these examples are subject to system-specific variation 
sprintf '<%f>'1;    # OUTPUT: «"<1.000000>"␤» 
sprintf '<%.1f>'1;  # OUTPUT: «"<1.0>"␤» 
sprintf '<%.0f>'1;  # OUTPUT: «"<1>"␤» 
sprintf '<%e>'10;   # OUTPUT: «"<1.000000e+01>"␤» 
sprintf '<%.1e>'10# OUTPUT: «"<1.0e+01>"␤» 

For "g" and "G", this specifies the maximum number of digits to show, including those prior to the decimal point and those after it; for example:

# These examples are subject to system-specific variation. 
sprintf '<%g>'1;        # OUTPUT: «<1>␤» 
sprintf '<%.10g>'1;     # OUTPUT: «<1>␤» 
sprintf '<%g>'100;      # OUTPUT: «<100>␤» 
sprintf '<%.1g>'100;    # OUTPUT: «<1e+02>␤» 
sprintf '<%.2g>'100.01# OUTPUT: «<1e+02>␤» 
sprintf '<%.5g>'100.01# OUTPUT: «<100.01>␤» 
sprintf '<%.4g>'100.01# OUTPUT: «<100>␤» 

For integer conversions, specifying a precision implies that the output of the number itself should be zero-padded to this width, where the 0 flag is ignored:

(Note that this feature currently works for unsigned integer conversions, but not for signed integer.)

NYI sprintf '<%.6d>'1;      # <000001> 
NYI sprintf '<%+.6d>'1;     # <+000001> 
NYI sprintf '<%-10.6d>'1;   # <000001    > 
NYI sprintf '<%10.6d>'1;    # <    000001> 
NYI sprintf '<%010.6d>'1;   #     000001> 
NYI sprintf '<%+10.6d>'1;   # <   +000001> 
sprintf '<%.6x>'1;         # OUTPUT: «<000001>␤» 
sprintf '<%#.6x>'1;        # OUTPUT: «<0x000001>␤» 
sprintf '<%-10.6x>'1;      # OUTPUT: «<000001    >␤» 
sprintf '<%10.6x>'1;       # OUTPUT: «<    000001>␤» 
sprintf '<%010.6x>'1;      # OUTPUT: «<    000001>␤» 
sprintf '<%#10.6x>'1;      # OUTPUT: «<  0x000001>␤» 

For string conversions, specifying a precision truncates the string to fit the specified width:

sprintf '<%.5s>'"truncated";   # OUTPUT: «<trunc>␤» 
sprintf '<%10.5s>'"truncated"# OUTPUT: «<     trunc>␤» 

You can also get the precision from the next argument using .*, or from a specified argument (e.g., with .*2$):

sprintf '<%.6x>'1;       # OUTPUT: «<000001>␤» 
sprintf '<%.*x>'61;    # OUTPUT: «<000001>␤» 
NYI sprintf '<%.*2$x>'16;  # "<000001>" 
NYI sprintf '<%6.*2$x>'14# "<  0001>" 

If a precision obtained through * is negative, it counts as having no precision at all:

sprintf '<%.*s>',  7"string";   # OUTPUT: «<string>␤» 
sprintf '<%.*s>',  3"string";   # OUTPUT: «<str>␤» 
sprintf '<%.*s>',  0"string";   # OUTPUT: «<>␤» 
sprintf '<%.*s>'-1"string";   # OUTPUT: «<string>␤» 
sprintf '<%.*d>',  10;          # OUTPUT: «<0>␤» 
sprintf '<%.*d>',  00;          # OUTPUT: «<>␤» 
sprintf '<%.*d>'-10;          # OUTPUT: «<0>␤» 

size

For numeric conversions, you can specify the size to interpret the number as using l, h, V, q, L, or ll. For integer conversions (d u o x X b i D U O), numbers are usually assumed to be whatever the default integer size is on your platform (usually 32 or 64 bits), but you can override this to use instead one of the standard C types, as supported by the compiler used to build Perl 6:

(Note: None of the following have been implemented.)

hh interpret integer as C type "char" or "unsigned char"
h interpret integer as C type "short" or "unsigned short"
j interpret integer as C type "intmax_t", 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"
z interpret integer as C type "size_t"

order of arguments

Normally, sprintf takes the next unused argument as the value to format for each format specification. If the format specification uses * to require additional arguments, these are consumed from the argument list in the order they appear in the format specification before the value to format. Where an argument is specified by an explicit index, this does not affect the normal order for the arguments, even when the explicitly specified index would have been the next argument.

So:

my $a = 5my $b = 2my $c = 'net';
sprintf "<%*.*s>"$a$b$c# OUTPUT: «<   ne>␤» 

uses $a for the width, $b for the precision, and $c as the value to format; while:

  NYI sprintf '<%*1$.*s>'$a$b;

would use $a for the width and precision and $b as the value to format.

Here are some more examples; be aware that when using an explicit index, the $ may need escaping:

 sprintf "%2\$d %d\n",      1234;     # OUTPUT: «34 12␤␤» 
 sprintf "%2\$d %d %d\n",   1234;     # OUTPUT: «34 12 34␤␤» 
 sprintf "%3\$d %d %d\n",   123456# OUTPUT: «56 12 34␤␤» 
 NYI sprintf "%2\$*3\$d %d\n",  1234,  3# " 34 12\n" 
 NYI sprintf "%*1\$.*f\n",       4,  510# "5.0000\n" 

Other examples:

 NYI sprintf "%ld a big number"4294967295;
 NYI sprintf "%%lld a bigger number"4294967296;
 sprintf('%c'97);                  # OUTPUT: «a␤» 
 sprintf("%.2f"1.969);             # OUTPUT: «1.97␤» 
 sprintf("%+.3f"3.141592);         # OUTPUT: «+3.142␤» 
 sprintf('%2$d %1$d'1234);       # OUTPUT: «34 12␤» 
 sprintf("%x"255);                 # OUTPUT: «ff␤» 

Special case: 'sprintf("<b>%s</b>\n", "Perl 6")' will not work, but one of the following will:

sprintf Q:b "<b>%s</b>\n",  "Perl 6"# OUTPUT: «<b>Perl 6</b>␤␤» 
sprintf     "<b>\%s</b>\n""Perl 6"# OUTPUT: «<b>Perl 6</b>␤␤» 
sprintf     "<b>%s\</b>\n""Perl 6"# OUTPUT: «<b>Perl 6</b>␤␤»