reading data from a file into a 2d array

V

Vladimir S. Oka

Ben said:
I know you can have empty data! I meant the program exhibited UB when
presented with an empty file because of what is does *after* testing
for
eof. The test if fine, but it won't return true so scanf is called
with no data to read -- that was what I was trying to say with "...
because
there may be no data to read". I should have been more explicit about
the UB comming from the read, not the eof test.


I don't think so. The fscanf is in the "else". It was the main point
I wanted to correct.

Sorry, I failed to notice a trailing `{` in the `else` part, and didn't
count the bottom ones. I saw just a `;` after `printf` and mentally
terminated the `else`. Comes from being used to a different coding
style that mandates curly braces on their own lines.
I thought that feof would not return true unless an input operation
had
failed. I may not be up on the latest standard so I will await
correction here, but if I am not mistaken your suggestion involved
reading when there might be nothing to read (and hence demons etc...).

As a I looked it up in the Standard, the `feof` does not require any
data to be read before testing for EOF condition. Looking elsethread, I
see that I have failed to test success of `fscanf`, and relied only on
`feof` for looping, but that's a different issue, I think.

--
BR, Vladimir

Hatred, n.:
A sentiment appropriate to the occasion of another's
superiority.
-- Ambrose Bierce, "The Devil's Dictionary"
 
B

Ben Bacarisse

As a I looked it up in the Standard, the `feof` does not require any data
to be read before testing for EOF condition. Looking elsethread, I see
that I have failed to test success of `fscanf`, and relied only on `feof`
for looping, but that's a different issue, I think.

It is possible we are having an agreement! feof does not need any data to
be read before testing, but it can never be true unless data has been read
(read standard entry for fopen) so loop that use it are, at best,
suspicious. All I was saying is that your loop used fscanf (again
well-defined when there is no data) to read into *uninitialied variables*
when there was no data, hence was not a good candidate to show a beginner.

The UB is from your whole loop failing to do something defined when there
is no data. The OP's loop had the same UB and I was critised twice for
pointing it out!
 
B

Ben Bacarisse

This is correct. Not only must an input operation have failed, it must
have failed due to EOF. If it fails due to file-error (corrupted file,
unreadable CD-ROM, etc), you will get repeated "EOF" indications from read
operations, but feof(fp) will remain false.

Thank you.

I was so puzzled by two people saying I was wrong that I downloaded a
recent draft standard to see if this behaviour was now in doubt -- and, of
course, I find that it not. I can see that I will have alter my writing
style: "I thought that..." should have been "I am certain that..."!
 
M

Micah Cowan

Chris Torek said:
This code fragment does not use "nread" after exiting the loop.

Um, quite. Guess I though I was gonna need it... and then didn't.
This is a good idea; however, doing so requires discarding the
scanf system, as "%u" includes an implicit "skip whitespace"
directive, and "whitespace" includes newlines.No amount of fiddling
with the scan format can repair this problem. The *only* solution
is to read input with something other than scanf (or, overly
complicated, scanf combined with something other than scanf, or
scanf with "%c" to read one character at a time, but these are just
silly ways of proving you can cut cheese with a "knife" made of
tofu).

Yup. I knew this, but probably should've mentioned it at that
point. Thanks for elaborating.
 
R

Rod Pemberton

Keith Thompson said:
If you melt the cheese and dip the knife in liquid nitrogen

, the cold knife will shatter when it hits the hot cheese.

Rod Pemberton
 
D

Dave Thompson

It is possible we are having an agreement! feof does not need any data to
be read before testing, but it can never be true unless data has been read
(read standard entry for fopen) so loop that use it are, at best,
suspicious. <snip>

To be precise, feof (and ferror for input) can only be true after an
_attempt_ has been made to read data, but that could be without
actually succeeding in reading anything.

And while I'm at it, to be really picky, test-at-top (while) loops
using feof are suspicious. Test-at-bottom (do-while) can be correct
though rarely useful since you usually need N-and-a-half or at least
N-and-a-fraction-that-fits-in-the-while-test.

- David.Thompson1 at worldnet.att.net
 
B

Ben Pfaff

Dave Thompson said:
And while I'm at it, to be really picky, test-at-top (while) loops
using feof are suspicious. Test-at-bottom (do-while) can be correct
though rarely useful since you usually need N-and-a-half or at least
N-and-a-fraction-that-fits-in-the-while-test.

In my experience, feof() should only be tested after a read has
failed, so that you can tell whether it failed due to a read
error or end-of-file. ferror() serves a similar purpose.
 
P

pete

Ben Pfaff wrote:
In my experience, feof() should only be tested after a read has
failed, so that you can tell whether it failed due to a read
error or end-of-file.

Dan Pop liked to use an feof test after this kind of a scanf call.
He said it had something to do with "sticky EOF".

rc = scanf("%" xstr(LENGTH) "[^\n]%*[^\n]", array);
if (!feof(stdin)) {
getchar();
}
 
B

Ben Pfaff

pete said:
Dan Pop liked to use an feof test after this kind of a scanf call.
He said it had something to do with "sticky EOF".

I won't claim to fathom the full meaning of scanf(), or Dan Pop.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,770
Messages
2,569,584
Members
45,075
Latest member
MakersCBDBloodSupport

Latest Threads

Top