digitalmars.D - Appending char[] to char[][] has unexpected results
- Tim Keating (26/26) Apr 30 2013 Not sure whether this is a bug, or perhaps I'm misunderstanding
- anonymous (9/36) Apr 30 2013 Just outBuf ~= buf.dup; works, too. Without .dup you're
- Tim Keating (4/12) May 01 2013 Okay, that was obviously the bit I was missing. The dchar
- Peter Alexander (26/38) May 01 2013 The wchar and dchar versions don't reuse the buffer. Not sure
- Steven Schveighoffer (19/21) May 01 2013 Wow, that is really awful.
- Steven Schveighoffer (5/16) May 01 2013 Note that it could have worked even with utf8 depending on the input
Not sure whether this is a bug, or perhaps I'm misunderstanding something, but it seems like this should work: void main() { char[][] outBuf; auto f = File("testData.txt", "r"); char[] buf; writeln("\n**** RAW OUTPUT *****"); while (f.readln(buf)) { write(buf); outBuf ~= buf; } writeln("\n**** BUFFERED OUTPUT *****"); foreach (line; outBuf) { write(line); } } testData.txt is just a couple of lines of miscellaneous text. The expectation is that the raw output and the buffered output should be exactly the same... but they are not. (If anyone would like to see this for themselves, I stuck it in github: https://github.com/MrTact/CharBug.) Changing the types of outBuf and buf to dchar works as expected. Changing outBuf to a string[] and appending buf.idup does as well.
Apr 30 2013
On Wednesday, 1 May 2013 at 03:54:23 UTC, Tim Keating wrote:Not sure whether this is a bug, or perhaps I'm misunderstanding something, but it seems like this should work: void main() { char[][] outBuf; auto f = File("testData.txt", "r"); char[] buf; writeln("\n**** RAW OUTPUT *****"); while (f.readln(buf)) { write(buf); outBuf ~= buf; } writeln("\n**** BUFFERED OUTPUT *****"); foreach (line; outBuf) { write(line); } } testData.txt is just a couple of lines of miscellaneous text. The expectation is that the raw output and the buffered output should be exactly the same... but they are not. (If anyone would like to see this for themselves, I stuck it in github: https://github.com/MrTact/CharBug.) Changing the types of outBuf and buf to dchar works as expected. Changing outBuf to a string[] and appending buf.idup does as well.Just outBuf ~= buf.dup; works, too. Without .dup you're overwriting and appending the same chunk of memory again and again. From the documentation on File.readln (<http://dlang.org/phobos/std_stdio#readln>): "Note that reusing the buffer means that the previous contents of it has to be copied if needed." I'm a bit puzzled as for why it behaves differently with dchar.
Apr 30 2013
On Wednesday, 1 May 2013 at 04:33:28 UTC, anonymous wrote:Just outBuf ~= buf.dup; works, too. Without .dup you're overwriting and appending the same chunk of memory again and again. From the documentation on File.readln (<http://dlang.org/phobos/std_stdio#readln>): "Note that reusing the buffer means that the previous contents of it has to be copied if needed." I'm a bit puzzled as for why it behaves differently with dchar.Okay, that was obviously the bit I was missing. The dchar situation IS baffling -- if that hadn't worked, I would have been more certain I was simply doing something wrong.
May 01 2013
On Wednesday, 1 May 2013 at 13:56:48 UTC, Tim Keating wrote:On Wednesday, 1 May 2013 at 04:33:28 UTC, anonymous wrote:The wchar and dchar versions don't reuse the buffer. Not sure why. Here's the implementation, complete with relevant TODO size_t readln(C)(ref C[] buf, dchar terminator = '\n') if (isSomeChar!C && !is(C == enum)) { static if (is(C == char)) { enforce(_p && _p.handle, "Attempt to read from an unopened file."); return readlnImpl(_p.handle, buf, terminator); } else { // TODO: optimize this string s = readln(terminator); if (!s.length) return 0; buf.length = 0; foreach (wchar c; s) { buf ~= c; } return buf.length; } } Oh dear!Just outBuf ~= buf.dup; works, too. Without .dup you're overwriting and appending the same chunk of memory again and again. From the documentation on File.readln (<http://dlang.org/phobos/std_stdio#readln>): "Note that reusing the buffer means that the previous contents of it has to be copied if needed." I'm a bit puzzled as for why it behaves differently with dchar.Okay, that was obviously the bit I was missing. The dchar situation IS baffling -- if that hadn't worked, I would have been more certain I was simply doing something wrong.
May 01 2013
On Wed, 01 May 2013 13:19:16 -0700, Peter Alexander <peter.alexander.au gmail.com> wrote:The wchar and dchar versions don't reuse the buffer. Not sure why. Here's the implementation, complete with relevant TODOWow, that is really awful. Needs immediate improvement. I would say the following code would be at least a bandaid-fix: ... if(buf.length == buf.capacity) { buf.length = 0; buf.assumeSafeAppend(); } else { buf.length = 0; } foreach (wchar c; s) { buf ~= c; } ... Refactor as desired. -Steve
May 01 2013
On Wed, 01 May 2013 06:56:47 -0700, Tim Keating <mrtact gmail.com> wrote:On Wednesday, 1 May 2013 at 04:33:28 UTC, anonymous wrote:Note that it could have worked even with utf8 depending on the input file. Although I agree the library code is not ideal, this is not an excuse ;) -SteveJust outBuf ~= buf.dup; works, too. Without .dup you're overwriting and appending the same chunk of memory again and again. From the documentation on File.readln (<http://dlang.org/phobos/std_stdio#readln>): "Note that reusing the buffer means that the previous contents of it has to be copied if needed." I'm a bit puzzled as for why it behaves differently with dchar.Okay, that was obviously the bit I was missing. The dchar situation IS baffling -- if that hadn't worked, I would have been more certain I was simply doing something wrong.
May 01 2013