Function std.format.formattedWrite
Interprets variadic argument list args
, formats them according
to fmt
, and sends the resulting characters to w
. The
encoding of the output is the same as Char
. The type Writer
must satisfy
.
isOutputRange
!(Writer, Char)
uint formattedWrite(alias fmt, Writer, A...)
(
auto ref Writer w,
A args
)
if (isSomeString!(typeof(fmt)));
uint formattedWrite(Writer, Char, A...)
(
auto ref Writer w,
in Char[] fmt,
A args
);
The variadic arguments are normally consumed in order. POSIX-style
positional parameter syntax is also supported. Each argument is
formatted into a sequence of chars according to the format
specification, and the characters are passed to w
. As many
arguments as specified in the format string are consumed and
formatted. If there are fewer arguments than format specifiers, a
FormatException
is thrown. If there are more remaining arguments
than needed by the format specification, they are ignored but only
if at least one argument was formatted.
The format string supports the formatting of array and nested array elements via the grouping format specifiers %( and %). Each matching pair of %( and %) corresponds with a single array argument. The enclosed sub-format string is applied to individual array elements. The trailing portion of the sub-format string following the conversion specifier for the array element is interpreted as the array delimiter, and is therefore omitted following the last array element. The %| specifier may be used to explicitly indicate the start of the delimiter, so that the preceding portion of the string will be included following the last array element. (See below for explicit examples.)
Parameters
Name | Description |
---|---|
w | Output is sent to this writer. Typical output writers include
Appender!string and std .
|
fmt | Format string. |
args | Variadic argument list. |
Returns
Formatted number of arguments.
Throws
Mismatched arguments and formats result in a FormatException
being thrown.
Format String
Format strings consist of characters interspersed with format specifications. Characters are simply copied to the output (such as putc) after any necessary conversion to the corresponding UTF-8 sequence.
The format string has the following grammar:
FormatString: FormatStringItem* FormatStringItem: '%%' '%' Position Flags Width Separator Precision FormatChar '%(' FormatString '%)' OtherCharacterExceptPercent Position: empty Integer '$' Flags: empty '-' Flags '+' Flags '#' Flags '0' Flags ' ' Flags Width: empty Integer '*' Separator: empty ',' ',' '?' ',' '*' '?' ',' Integer '?' ',' '*' ',' Integer Precision: empty '.' '.' Integer '.*' Integer: Digit Digit Integer Digit: '0'|'1'|'2'|'3'|'4'|'5'|'6'|'7'|'8'|'9' FormatChar: 's'|'c'|'b'|'d'|'o'|'x'|'X'|'e'|'E'|'f'|'F'|'g'|'G'|'a'|'A'|'|'
Flag | Types affected | Semantics |
---|---|---|
'-' | numeric | Left justify the result in the field. It overrides any 0 flag. |
'+' | numeric | Prefix positive numbers in a signed conversion with a +. It overrides any space flag. |
'#' | integral ('o') | Add to precision as necessary so that the first digit of the octal formatting is a '0', even if both the argument and the Precision are zero. |
'#' | integral ('x', 'X') | If non-zero, prefix result with 0x (0X). |
'#' | floating | Always insert the decimal point and print trailing zeros. |
'0' | numeric | Use leading
zeros to pad rather than spaces (except for the floating point
values nan and infinity ). Ignore if there's a Precision. |
' ' | numeric | Prefix positive numbers in a signed conversion with a space. |
- Width
- Specifies the minimum field width. If the width is a *, an additional argument of type int, preceding the actual argument, is taken as the width. If the width is negative, it is as if the - was given as a Flags character.
- Precision
- Gives the precision for numeric conversions. If the precision is a *, an additional argument of type int, preceding the actual argument, is taken as the precision. If it is negative, it is as if there was no Precision specifier.
- Separator
- Inserts the separator symbols ',' every X digits, from right to left, into numeric values to increase readability. The fractional part of floating point values inserts the separator from left to right. Entering an integer after the ',' allows to specify X. If a '*' is placed after the ',' then X is specified by an additional parameter to the format function. Adding a '?' after the ',' or X specifier allows to specify the separator character as an additional parameter.
- FormatChar
-
- 's'
- The corresponding argument is formatted in a manner consistent
with its type:
- bool
- The result is
"true"
or"false"
. - integral types
- The %d format is used.
- floating point types
- The %g format is used.
- string types
- The result is the string converted to UTF-8. A Precision specifies the maximum number of characters to use in the result.
- structs
- If the struct defines a toString() method the result is the string returned from this function. Otherwise the result is StructName(field0, field1, ...) where fieldn is the nth element formatted with the default format.
- classes derived from Object
- The result is the string returned from the class instance's .toString() method. A Precision specifies the maximum number of characters to use in the result.
- unions
- If the union defines a toString() method the result is the string returned from this function. Otherwise the result is the name of the union, without its contents.
- non-string static and dynamic arrays
- The result is [s0, s1, ...] where sn is the nth element formatted with the default format.
- associative arrays
- The result is the equivalent of what the initializer would look like for the contents of the associative array, e.g.: ["red" : 10, "blue" : 20].
- 'c'
- The corresponding argument must be a character type.
- 'b','d','o','x','X'
- The corresponding argument must be an integral type and is formatted as an integer. If the argument is a signed type and the FormatChar is d it is converted to a signed string of characters, otherwise it is treated as unsigned. An argument of type bool is formatted as '1' or '0'. The base used is binary for b, octal for o, decimal for d, and hexadecimal for x or X. x formats using lower case letters, X uppercase. If there are fewer resulting digits than the Precision, leading zeros are used as necessary. If the Precision is 0 and the number is 0, no digits result.
- 'e','E'
- A floating point number is formatted as one digit before the decimal point, Precision digits after, the FormatChar, ±, followed by at least a two digit exponent: d.dddddde±dd. If there is no Precision, six digits are generated after the decimal point. If the Precision is 0, no decimal point is generated.
- 'f','F'
- A floating point number is formatted in decimal notation. The Precision specifies the number of digits generated after the decimal point. It defaults to six. At least one digit is generated before the decimal point. If the Precision is zero, no decimal point is generated.
- 'g','G'
- A floating point number is formatted in either e or f format for g; E or F format for G. The f format is used if the exponent for an e format is greater than -5 and less than the Precision. The Precision specifies the number of significant digits, and defaults to six. Trailing zeros are elided after the decimal point, if the fractional part is zero then no decimal point is generated.
- 'a','A'
- A floating point number is formatted in hexadecimal exponential notation 0xh.hhhhhhp±d. There is one hexadecimal digit before the decimal point, and as many after as specified by the Precision. If the Precision is zero, no decimal point is generated. If there is no Precision, as many hexadecimal digits as necessary to exactly represent the mantissa are generated. The exponent is written in as few digits as possible, but at least one, is in decimal, and represents a power of 2 as in h.hhhhhh*2±d. The exponent for zero is zero. The hexadecimal digits, x and p are in upper case if the FormatChar is upper case.
Floating point NaN's are formatted as nan if the FormatChar is lower case, or NAN if upper. Floating point infinities are formatted as inf or infinity if the FormatChar is lower case, or INF or INFINITY if upper.
The positional and non-positional styles can be mixed in the same format string. (POSIX leaves this behavior undefined.) The internal counter for non-positional parameters tracks the next parameter after the largest positional parameter already used.
Example using array and nested array formatting:
import std .stdio;
void main()
{
writefln("My items are %(%s %).", [1,2,3]);
writefln("My items are %(%s, %).", [1,2,3]);
}
The output is:
My items are 1 2 3. My items are 1, 2, 3.
The trailing end of the sub-format string following the specifier for each item is interpreted as the array delimiter, and is therefore omitted following the last array item. The %| delimiter specifier may be used to indicate where the delimiter begins, so that the portion of the format string prior to it will be retained in the last array element:
import std .stdio;
void main()
{
writefln("My items are %(-%s-%|, %).", [1,2,3]);
}
which gives the output:
My items are -1-, -2-, -3-.
These compound format specifiers may be nested in the case of a nested array argument:
import std .stdio;
void main() {
auto mat = [[1, 2, 3],
[4, 5, 6],
[7, 8, 9]];
writefln("%(%(%d %)\n%)", mat);
writeln();
writefln("[%(%(%d %)\n %)]", mat);
writeln();
writefln("[%([%(%d %)]%|\n %)]", mat);
writeln();
}
The output is:
1 2 3 4 5 6 7 8 9 [1 2 3 4 5 6 7 8 9] [[1 2 3] [4 5 6] [7 8 9]]
Inside a compound format specifier, strings and characters are escaped
automatically. To avoid this behavior, add '-' flag to
"%("
.
import std .stdio;
void main()
{
writefln("My friends are %s.", ["John", "Nancy"]);
writefln("My friends are %(%s, %).", ["John", "Nancy"]);
writefln("My friends are %-(%s, %).", ["John", "Nancy"]);
}
which gives the output:
My friends are ["John", "Nancy"]. My friends are "John", "Nancy". My friends are John, Nancy.
Example
The format string can be checked at compile-time (see format
for details):
import std .array : appender;
auto writer = appender!string();
writer .formattedWrite!"%s is the ultimate %s."(42, "answer");
writeln(writer .data); // "42 is the ultimate answer."
// Clear the writer
writer = appender!string();
formattedWrite(writer, "Date: %2$s %1$s", "October", 5);
writeln(writer .data); // "Date: 5 October"
Example
writeln(format("%,d", 1000)); // "1,000"
writeln(format("%,f", 1234567.891011)); // "1,234,567.891,011"
writeln(format("%,?d", '?', 1000)); // "1?000"
writeln(format("%,1d", 1000)); // "1,0,0,0"
writeln(format("%,*d", 4, -12345)); // "-1,2345"
writeln(format("%,*?d", 4, '_', -12345)); // "-1_2345"
writeln(format("%,6?d", '_', -12345678)); // "-12_345678"
assert(format("%12,3.3f", 1234.5678) == " 1,234.568", "'" ~
format("%12,3.3f", 1234.5678) ~ "'");
Authors
Walter Bright, Andrei Alexandrescu, and Kenji Hara