Thread overview
Weird behaviour with File.eof
Sep 20, 2015
Dandyvica
Sep 20, 2015
Daniel Kozák
Sep 22, 2015
crimaniak
September 20, 2015
Hi all,

I can't explain to myself this weird behavior:

void main(string[] argv)
{
	char[] line;
	auto fh = File(argv[1]);
	while (!fh.eof) {
		writef("before readln eof=%s, ", fh.eof);
		fh.readln(line,std.ascii.newline);
		writefln("line=<%s>, after readln eof=%s",chomp(line), fh.eof);
	}
	fh.close();
}

My file is made of 10 lines:


cat numbers.txt
1
2
3
4
5
6
7
8
9
10

╰─$ wc -l numbers.txt
10 numbers.txt

When run:

before readln eof=false, line=<1>, after readln eof=false
before readln eof=false, line=<2>, after readln eof=false
before readln eof=false, line=<3>, after readln eof=false
before readln eof=false, line=<4>, after readln eof=false
before readln eof=false, line=<5>, after readln eof=false
before readln eof=false, line=<6>, after readln eof=false
before readln eof=false, line=<7>, after readln eof=false
before readln eof=false, line=<8>, after readln eof=false
before readln eof=false, line=<9>, after readln eof=false
before readln eof=false, line=<10>, after readln eof=false
before readln eof=false, line=<>, after readln eof=true

I can't explain why eof is not set to true after reading the last line ?!

Last DMD 2.68.1.0, Linux Mint 17.2.


Thanks for any clue.
September 20, 2015
V Sun, 20 Sep 2015 20:17:36 +0000
Dandyvica via Digitalmars-d-learn <digitalmars-d-learn@puremagic.com>
napsáno:

> Hi all,
> 
> I can't explain to myself this weird behavior:
> 
> void main(string[] argv)
> {
> 	char[] line;
> 	auto fh = File(argv[1]);
> 	while (!fh.eof) {
> 		writef("before readln eof=%s, ", fh.eof);
> 		fh.readln(line,std.ascii.newline);
> 		writefln("line=<%s>, after readln
> eof=%s",chomp(line), fh.eof); }
> 	fh.close();
> }
> 
> My file is made of 10 lines:
> 
> 
> cat numbers.txt
> 1
> 2
> 3
> 4
> 5
> 6
> 7
> 8
> 9
> 10
> 
> ╰─$ wc -l numbers.txt
> 10 numbers.txt
> 
> When run:
> 
> before readln eof=false, line=<1>, after readln eof=false before readln eof=false, line=<2>, after readln eof=false before readln eof=false, line=<3>, after readln eof=false before readln eof=false, line=<4>, after readln eof=false before readln eof=false, line=<5>, after readln eof=false before readln eof=false, line=<6>, after readln eof=false before readln eof=false, line=<7>, after readln eof=false before readln eof=false, line=<8>, after readln eof=false before readln eof=false, line=<9>, after readln eof=false before readln eof=false, line=<10>, after readln eof=false before readln eof=false, line=<>, after readln eof=true
> 
> I can't explain why eof is not set to true after reading the last line ?!
> 
> Last DMD 2.68.1.0, Linux Mint 17.2.
> 
> 
> Thanks for any clue.

This is normal behavior

http://www.cplusplus.com/reference/cstdio/feof/

"Notice that stream's internal position indicator may point to the end-of-file for the next operation, but still, the end-of-file indicator may not be set until an operation attempts to read at that point."

September 22, 2015
On Sunday, 20 September 2015 at 20:17:37 UTC, Dandyvica wrote:

> My file is made of 10 lines:
>
>
> cat numbers.txt
> 1
> 2
> 3
> 4
> 5
> 6
> 7
> 8
> 9
> 10
>
> ╰─$ wc -l numbers.txt
CR/LF can be interpreted as line _dividers_, so if you have CR or CR/LF at the end of line 10, really here is line 11 which is empty. Remove end of line symbols at line 10 and you will have expected output:

before readln eof=false, line=<1>, after readln eof=false
before readln eof=false, line=<2>, after readln eof=false
before readln eof=false, line=<3>, after readln eof=false
before readln eof=false, line=<4>, after readln eof=false
before readln eof=false, line=<5>, after readln eof=false
before readln eof=false, line=<6>, after readln eof=false
before readln eof=false, line=<7>, after readln eof=false
before readln eof=false, line=<8>, after readln eof=false
before readln eof=false, line=<9>, after readln eof=false
before readln eof=false, line=<10>, after readln eof=true

p.s. it's good style to check input parameters, even for most simple cases.