Thread overview
Reading file by line, weird result
Dec 27, 2013
Dfr
Dec 27, 2013
lomereiter
Dec 27, 2013
Dfr
Dec 27, 2013
Marco Leise
December 27, 2013
Hello, here is simple pice of code to read text file into array of lines:

import std.stdio;

void main(string args[]) {
    auto file = File(args[1]);
    auto frange = file.byLine();
    char[][] buf;
    foreach (char[] line; frange) {
        buf = buf ~ line;
    }
    writeln(buf);
}

When i run this code for this text file:
--------------cutline-----------
hello
world
of D
and
have a nice day
--------------cutline-----------

then program prints:

["and\n\n", "and\n\n", "and\n", "and", "have a nice day!"]

As you can see, this is complete madness, any idea what is wrong here ?

December 27, 2013
The solution is to append `line.dup` instead of `line`.

I guess this note in the documentation should be marked red:
> Each front will not persist after popFront is called, so the caller must copy its contents (e.g. by calling to!string) if retention is needed.
December 27, 2013
On Friday, 27 December 2013 at 09:44:22 UTC, lomereiter wrote:
> The solution is to append `line.dup` instead of `line`.
>
> I guess this note in the documentation should be marked red:
>> Each front will not persist after popFront is called, so the caller must copy its contents (e.g. by calling to!string) if retention is needed.

Thank you, .dup helped.
December 27, 2013
Am Fri, 27 Dec 2013 10:24:15 +0000
schrieb "Dfr" <deflexor@yandex.ru>:

> On Friday, 27 December 2013 at 09:44:22 UTC, lomereiter wrote:
> > The solution is to append `line.dup` instead of `line`.
> >
> > I guess this note in the documentation should be marked red:
> >> Each front will not persist after popFront is called, so the caller must copy its contents (e.g. by calling to!string) if retention is needed.
> 
> Thank you, .dup helped.

To avoid allocating new memory for each line of text, byLine reuses the buffer. You are supposed to make a duplicate if you plan to keep it. It would be different if you had:

  string s;
  foreach (line; frange) {
      s ~= line
  }

in which case, the _contents_ of the line buffer, not the buffer itself are appended to the string s.

-- 
Marco