Formatted read consumes input

Dmitry Olshansky dmitry.olsh at gmail.com
Fri Aug 24 04:18:53 PDT 2012


On Thursday, 23 August 2012 at 11:33:19 UTC, monarch_dodra wrote:
> As title implies:
>
> ----
> import std.stdio;
> import std.format;
>
> void main()
> {
>   string s = "42";
>   int v;
>   formattedRead(s, "%d", &v);
>   writefln("[%s] [%s]", s, v);
> }
> ----
> [] [42]
> ----
>
> Is this the "expected" behavior?

Yes, both parse family and formattedRead are operating on ref 
argument. That means they modify in place. Also ponder the 
thought that 2 consecutive reads should obviously read first and 
2nd value in the string not the same one.


> Furthermore, it is not possible to try to "save" s:
> ----
> import std.stdio;
> import std.format;
> import std.range;
>
> void main()
> {
>   string s = "42";
>   int v;
>   formattedRead(s.save, "%d", &v);
>   writefln("[%s] [%s]", s, v);
> }
> ----

Yes, because ref doesn't bind r-value.

> The workaround is to have a named backup:
>   auto ss = s.save;
>   formattedRead(ss, "%d", &v);
>
>
> I've traced the root issue to formattedRead's signature, which 
> is:
> uint formattedRead(R, Char, S...)(ref R r, const(Char)[] fmt, S 
> args);
>

As I explained above the reason is because the only sane logic of 
multiple reads is to consume input and to do so it needs ref.

> Is there a particular reason for this pass by ref? It is 
> inconsistent with the rest of phobos, or even C's scanf?

C's scanf is a poor argument as it uses pointers instead of ref 
(and it can't do ref as there is no ref in C :) ). Yet it doesn't 
allow to read things in a couple of calls AFAIK. In C scanf 
returns number of arguments successfully read not bytes so there 
is no way to continue from where it stopped.

BTW it's not documented what formattedRead returns ... just ouch.


More information about the Digitalmars-d mailing list