std.string.format call from varyargs

drug via Digitalmars-d-learn digitalmars-d-learn at puremagic.com
Sun Jul 2 01:38:34 PDT 2017


02.07.2017 09:52, H. S. Teoh via Digitalmars-d-learn пишет:
> On Sun, Jul 02, 2017 at 12:49:30AM +0000, LeqxLeqx via Digitalmars-d-learn wrote:
>> Hello!
>>
>> How does one go about invoking a templated-variatic function such as
>> std.string.format with an array of objects?
>>
>> For example:
>>
>> string stringMyThing (string formatForMyThings, MyThing[] myThings)
>> {
>>    return format(
>>      formatForMyThings,
>>      myThings
>>      );
>> }
>>
>>
>>
>> In executing the above, the 'format' method always interprets the
>> entire array 'myThings' as the first argument to the format, and no
>> arguments afterwards, resulting in 'orphaned' format specifiers if the
>> array is longer than a single element. Even if the array is only a
>> single element, the formatter will wrap the result of the element's
>> 'toString()' method with '[' and ']'
>>
>> I really don't want to write my own format parser.
>> Any help would be much appreciated!
> [...]
> 
> Take a look at the docs that describe the "%(...%)" nested format
> specifiers.  For example:
> 
> 	int[] arr = [ 1, 2, 3 ];
> 	writefln("%(%s | %)", arr);
> 
> Output:
> 
> 	1 | 2 | 3
> 
> Explanation: %(...%) means a nested format specifier, where the stuff
> enclosed between %( and %) are applied to each array element (actually,
> range element -- it works for arbitrary input ranges). In this case, the
> stuff in between is "%s | ", which is treated as "%s" followed by the
> delimiter " | ". So each array element is formatted with %s, and " | "
> is inserted as a delimiter.
> 
> A slightly more interesting example:
> 
> 	int[] arr = [ 1, 2, 3 ];
> 	writefln("%(<%s>%|, %)", arr);
> 
> Output:
> 
> 	<1>, <2>, <3>
> 
> Explanation: the stuff between %( and %) is "<%s>%|, ", which is
> understood as applying "<%s>" to each array element, and treating ", "
> as the delimiter. The "%|" separates the per-element component from the
> delimiter; this distinction is important because we want the ">" to
> appear after every element including the last one, but we don't want the
> ", " to appear after the last element.
> 
> You can also nest %(...%) to handle multidimensional arrays. Here's my
> favorite example:
> 
> 	auto m = [ [ 1, 2, 3 ], [ 4, 5, 6 ], [ 7, 8, 9 ] ];
> 	writefln("%([ %(%s, %) ]%|\n%)", m);
> 
> Output:
> 
> 	[ 1, 2, 3 ]
> 	[ 4, 5, 6 ]
> 	[ 7, 8, 9 ]
> 
> Hope this helps!
> 
> 
> T
> 
Cool! Is it D only or could be used in printf (C/C++)?


More information about the Digitalmars-d-learn mailing list