post-loop
<block quote>
IMO the problem is that EOF is simultaneously a character in the
stream and some sort of abstraction representing the end of the
stream.
<snips>
|
IIRC is.good() holds even if next op is is.get() == EOF;
is.good() is meant to be true if characters are available, but IMO if
the next char is EOF then by definition no characters are available.
|
Further if EOF is a character and you are at eof(), then you should
IMO be able to is.putback(), but IIRC you can't.
|
I opted to wrap up text streams, so they all have the same semantic,
for files, console and strings. Any stream has a name, for files the
name of the file, for strings a name you supply and for console the
name of the console ( and a terminator you supply) Also every stream
keeps a record of line and column position, so you can output error
messages including name, and current position in a user friendly
format. Final part is a checkpoint stack, so you can create
checkpoints with useful messages, and they pop off the stack at the
end of their scope. Another stream type is a stream stack, where you
can push and pop streams (say for #include files, or macros. Its not
perfect as ideally you should be able to pushback through eof, but
because of the semantics of std::stteams this isnt really feasible.
However I do despair of the std::streams ...
I expect I will hear other opinions from experts about the issue
Thank you very much, Andy, this is useful info, but in my case the problem
was really my own stupidity: I was reading a file with number comma number
comma number newline number comma (etc), commas as delimiters, newlines for
human readbility.
Alf's code used one read in the loop, and I tried his code, which got the
first number and then stopped (next item was a comma, which didn't fit type
double, so the loop broke out).
I thought: why not add a second read, of char type (but use it like a
throwaway, never use the character collected by it), and see what happens?
What happened was the loop read the whole file (almost).
Bingo! Just what I wanted originally, had solved with dozens of lines of
ugly code, and now saw could be vastly easier and prettier. (It also
revealed another stupidity: I assumed --for no reason-- that the numbers in
the file were stored as characters. They were not. I didn't need to do any
strtod() or c_str() at all).
Anyway, what was wrong was that I had put the read-a-double instruction
first in the loop, and the read-a-character second, so when the loop
finished, the read-a-number instruction never got executed, leaving the last
number in the file still hanging out there.
Reversing the order of the reads _did_ get the last number, but would not
read the file _at_all_ since the _first_ thing in the file was a number and
now the loop was expecting a characer first.
BUT: O, beautiful synergy: as it happens, the first file line's three
numbers (the rest have five) are not intended to go into my x,y,z,r,c
database, so all I had to do was read these three and their two char type
commas (but _not_ read the newline) _outside_ of the loop, which then gave
the loop exactly what it expected (a char first --the \n-- in the loop-read)
when I went inside the loop to fill the database with numbers.
IOW, it was merely a matter of which, a number or a character, I read first
in the loop. If the number first, it missed the last number, and if the
char first, it missed the whole file. (I could also have forced my
file_writer_ to stick a comma into position 0 in the file, but that'd have
been a major kludge; ugly and obviously a very clumsy workaround).
Thanks for the more info, Andy (and Alf), but this seems to have been a case
of a neophyte (me) doing something _so_ obvious and stupid that the experts
here (you included) didn't see what sheer idiocy I had perpetrated upon
myself.
(*grin*)