www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - Reading file by line, weird result

reply "Dfr" <deflexor yandex.ru> writes:
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 ?
Dec 27 2013
parent reply "lomereiter" <lomereiter gmail.com> writes:
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.
Dec 27 2013
parent reply "Dfr" <deflexor yandex.ru> writes:
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.
Dec 27 2013
parent Marco Leise <Marco.Leise gmx.de> writes:
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
Dec 27 2013