Thread overview
How to make a formatted string ?
Mar 17, 2010
Gabriel Laskar
Mar 17, 2010
Gabriel Laskar
Mar 17, 2010
Gabriel Laskar
Mar 17, 2010
Gabriel Laskar
Mar 17, 2010
Ellery Newcomer
March 17, 2010
Hi,

I am searching how to do a formatted string like with sprintf()

I have found std.format.formattedWrite() but when I try :

Appender!(string) msg;
formattedWrite(msg, "toto: %0", 42);
writeln(msg);

It fails with :
core.exception.RangeError@�(1582): Range violation

I have also found std.string.format, but it seems to fail also.
March 17, 2010
Gabriel Laskar wrote:
> Hi,
> 
> I am searching how to do a formatted string like with sprintf()
> 
> I have found std.format.formattedWrite() but when I try :
> 
> Appender!(string) msg;
> formattedWrite(msg, "toto: %0", 42);
> writeln(msg);
> 
> It fails with :
> core.exception.RangeError@�(1582): Range violation
> 
> I have also found std.string.format, but it seems to fail also.

There are two problems here:

  1. Your format specification is wrong.  %0 is not a valid specifier.
  2. msg isn't a string, it's an Appender.  Extract its contents with
     Appender.data instead.

Here's one example of how to do it:

  Appender!string msg;
  formattedWrite(msg, "toto: %s", 42);
  write(msg.data);

If you meant to use positional parameters, then the first parameter is number 1, not 0, and you also need a format specifier.  The syntax is then

  formattedWrite(msg, "toto: %1$s", 42);

(This is the POSIX syntax, check out http://opengroup.org/onlinepubs/009695399/functions/printf.html for the full specification.)

-Lars
March 17, 2010
Gabriel Laskar wrote:
> I have also found std.string.format, but it seems to fail also.

I forgot to mention:  std.string.format() works if you use a correct format specification.

  string msg = format("hello: %s", 42);

It doesn't seem to support positional parameters, though.

-Lars
March 17, 2010
On 03/17/2010 12:59 PM, Gabriel Laskar wrote:
> Hi,
>
> I am searching how to do a formatted string like with sprintf()
>
> I have found std.format.formattedWrite() but when I try :
>
> Appender!(string) msg;
> formattedWrite(msg, "toto: %0", 42);
> writeln(msg);
>
> It fails with :
> core.exception.RangeError@�(1582): Range violation
>
> I have also found std.string.format, but it seems to fail also.

Oops, I'm stupid, It is not %0, but %s... std.string.format is good.
Now I need to pass an array of char[] instead of va_args, I have found
a work around, but it seems bad :

string formatArray(char[][] args)
{
  switch (args.length)
  {
    case 1: return format(args[0]);
    case 2: return format(args[0], args[1]);
    // ...
  }
}

If someone have something better...

Cheers.

__
Gabriel Laskar <gabriel@lse.epita.fr0>
March 17, 2010
Gabriel Laskar wrote:
> On 03/17/2010 12:59 PM, Gabriel Laskar wrote:
>> Hi,
>>
>> I am searching how to do a formatted string like with sprintf()
>>
>> I have found std.format.formattedWrite() but when I try :
>>
>> Appender!(string) msg;
>> formattedWrite(msg, "toto: %0", 42);
>> writeln(msg);
>>
>> It fails with :
>> core.exception.RangeError@�(1582): Range violation
>>
>> I have also found std.string.format, but it seems to fail also.
> 
> Oops, I'm stupid, It is not %0, but %s... std.string.format is good.
> Now I need to pass an array of char[] instead of va_args, I have found
> a work around, but it seems bad :
> 
> string formatArray(char[][] args)
> {
>   switch (args.length)
>   {
>     case 1: return format(args[0]);
>     case 2: return format(args[0], args[1]);
>     // ...
>   }
> }
> 
> If someone have something better...

It depends on what you are trying to do.

  char[][] a = ["hello".dup, "world".dup];
  string fmt = format(a);
  // fmt is now "[hello,world]"

  char[][] a = ["hello %s %s world".dup, "foo".dup, "bar".dup];
  string fmt = format(a[0], a[1 .. $]);
  // fmt is now "hello foo bar world"

 -Lars
March 17, 2010
On 03/17/2010 02:58 PM, Lars T. Kyllingstad wrote:
> char[][] a = ["hello %s %s world".dup, "foo".dup, "bar".dup];
> string fmt = format(a[0], a[1 .. $]);
> // fmt is now "hello foo bar world"

thats perfect, thanks

__
Gabriel Laskar <gabriel@lse.epita.fr0>
March 17, 2010
On 03/17/2010 02:58 PM, Lars T. Kyllingstad wrote:
> char[][] a = ["hello %s %s world".dup, "foo".dup, "bar".dup];
> string fmt = format(a[0], a[1 .. $]);
> // fmt is now "hello foo bar world"

I have another problem :

 1 import std.stdio;
 2 import std.string;
 3
 4 int main()
 5 {
 6   char[][] a = ["expected %s but found %s".dup, "42".dup, "32".dup];
 7
 8   writeln(format(a[0], a[1 .. $]));
 9
10   return 0;
11 }

Does not work :
$ dmd-phobos -run format.d
std.format.FormatError: std.format

but :

 1 import std.stdio;
 2 import std.string;
 3
 4 int main()
 5 {
 6   char[][] a = ["expected %s".dup, "42".dup];
 7
 8   writeln(format(a[0], a[1 .. $]));
 9
10   return 0;
11 }

does not seems to work either :
$ dmd-phobos -run format.d
expected [42]

Did I miss something ?

-- 
Gabriel Laskar <gabriel@lse.epita.fr>
March 17, 2010
On 03/17/2010 11:21 AM, Gabriel Laskar wrote:
>
> I have another problem :
>
> 1 import std.stdio;
> 2 import std.string;
> 3
> 4 int main()
> 5 {
> 6 char[][] a = ["expected %s but found %s".dup, "42".dup, "32".dup];
> 7
> 8 writeln(format(a[0], a[1 .. $]));
> 9
> 10 return 0;
> 11 }
>
> Does not work :
> $ dmd-phobos -run format.d
> std.format.FormatError: std.format

format wants to put the entire a[1 .. $] in the first %s. There isn't anything left over for the second %s
>
> but :
>
> 1 import std.stdio;
> 2 import std.string;
> 3
> 4 int main()
> 5 {
> 6 char[][] a = ["expected %s".dup, "42".dup];
> 7
> 8 writeln(format(a[0], a[1 .. $]));
> 9
> 10 return 0;
> 11 }
>
> does not seems to work either :
> $ dmd-phobos -run format.d
> expected [42]
>
> Did I miss something ?
>

ditto.

To get what you want, you're probably going to have to mess around with std.format.doFormat and implement your own format function.