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.