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.

Reply via email to