D issues are now tracked on GitHub. This Bugzilla instance remains as a read-only archive.
Issue 11995 - std.File.ByLine strips trailing empty line
Summary: std.File.ByLine strips trailing empty line
Status: RESOLVED INVALID
Alias: None
Product: D
Classification: Unclassified
Component: phobos (show other issues)
Version: D2
Hardware: All All
: P2 normal
Assignee: No Owner
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2014-01-25 12:34 UTC by monarchdodra
Modified: 2020-03-21 03:56 UTC (History)
3 users (show)

See Also:


Attachments

Note You need to log in before you can comment on or make changes to this issue.
Description monarchdodra 2014-01-25 12:34:33 UTC
//----
import std.stdio;
void main()
{
    File("stuff0", "w").write("line 1\nline 2");
    File("stuff1", "w").write("line 1\nline 2\n");
    File("stuff2", "w").write("line 1\nline 2\na");
    File("stuff3", "w").write("line 1\nline 2\n\n\n");
    writeln(File("stuff0").byLine());
    writeln(File("stuff1").byLine());
    writeln(File("stuff2").byLine());
    writeln(File("stuff3").byLine());
}
//----
["line 1", "line 2"]
["line 1", "line 2"]
["line 1", "line 2", "a"]
["line 1", "line 2", "", ""]
//----

The problem is that the last empty line is stripped away. This can be a problem for algorithms that copy/mutate files, as they can't reliably preserve the exact amount of lines to produce: File0 and File1 produced the exact same output, but are different :/

I think the correct output should be:
//----
["line 1", "line 2"]
["line 1", "line 2", ""]
["line 1", "line 2", "a"]
["line 1", "line 2", "", "", ""]
//----

With this scheme, it's simple: every line in the file gets an entry, and the last line of byLine does not actually have a terminator.

This means that something like:
File("out.txt", "w").writefln("%(%s\n%)", File("in.txt").byLine());
Will *exactly* duplicate the input file.
Comment 1 Peter Alexander 2014-01-25 16:07:40 UTC
I agree, but I wonder if this is too much of a breaking change? I imagine byLine is used a lot, and I could easily see use cases that would break on this change.
Comment 3 Peter Alexander 2014-01-26 04:16:01 UTC
(In reply to comment #2)
> Is this similar/dupe of http://d.puremagic.com/issues/show_bug.cgi?id=11830 and
> http://d.puremagic.com/issues/show_bug.cgi?id=11465?

No, they are both separate bugs. 11830 is a bug with the laziness of the implementation asumming front is called. 11465 is to do with line endings. This bug is about the treatment of trailing empty lines.
Comment 4 Rainer Schuetze 2014-12-13 07:42:08 UTC
I don't think this is a bug. The "standard" line has a trailing newline, you even get warned about it missing for the last line by various programs.

If you want to exactly reproduce the original text use KeepTerminator.yes. This also works for mixed line endings on Windows (CRLF and LF).
Comment 5 basile-z 2015-11-27 16:32:34 UTC
No, you forgot that the \n is part of the line:

your file is filled with:

"line 1\nline 2\n\n\n"

you expect byLine to output:

["line 1", "line 2", "", "", ""]

but "line 1\nline 2\n\n\n" contains **four** lines, not five:

line1\n
line2\n
\n
\n