which functions set the end-of-file indicator?

N

nicolas.sitbon

Hi everybody, in a french C book, the author says that only {fgetc,
getc, getchar, fgetwc, getwc, getwchar, fgets, gets, fgetws, getws,
fputc, putc, putchar, fputwc, putwc, putwchar, fputs, puts, fputws}
are guaranteed to set the end-of-file indicator when the end-of-file
is reached, but in C99 standard, I find p 288 (ISO/IEC 9899:TC3
Committee Draft — Septermber 7, 2007 WG14/N1256)

/* ============================= */
#include <stdio.h>
/* ... */
int count; float quant; char units[21], item[21];
do {
count = fscanf(stdin, "%f%20s of %20s", &quant, units, item);
fscanf(stdin,"%*[^\n]");
} while (!feof(stdin) && !ferror(stdin));
/* ============================= */
It seems to say that fscanf family function set end-of-file indicator
too? which functions set the end-of-file indicator?
 
V

vippstar

On Aug 4, 9:05 pm, (e-mail address removed) wrote:
It seems to say that fscanf family function set end-of-file indicator
too? which functions set the end-of-file indicator?

All functions that perform IO operations. (ie even perror() can set
the 'error' indicator for stderr if an error occurs at writing)
 
C

Chris Torek

Hi everybody, in a french C book, the author says that only {fgetc,
getc, getchar, fgetwc, getwc, getwchar, fgets, gets, fgetws, getws,
fputc, putc, putchar, fputwc, putwc, putwchar, fputs, puts, fputws}
are guaranteed to set the end-of-file indicator when the end-of-file
is reached ...

This is incorrect. In the "obviously wrong" part, putc() is not
going to set the end-of-file indicator, for instance. :) But it
is still wrong, and perhaps overly complicated.

All I/O is done "as if" via fgetc() and fputc(). If fgetc() would
have set the end-of-file indicator, any other input-oriented
operation that would have called fgetc() must also set the e-o-f
indicator. (And of course, if fgetc() would have set the error
indicator, any other input-oriented operation that would have called
fgetc() must also set the error indicator. The "would have"s here
simply mean that, deep inside the implementation, scanf() or fread()
or whatever might use something "faster" or "better" than an actual
call to fgetc(), such as an inline expansion of what fgetc() does.
But if they do avoid fgetc() in favor of something "better", they
still have to act *as if* they had made an actual call to fgetc(),
including setting the e-of-f and/or error indicators in the same
way that fgetc() would have.)

(For instance, an implementation might have a macro like this:

#define fast_inlined_getc(f) \
((f)->_readcount > 0 ? --(f)->_readcount, *(f)->_readptr++ : \
fgetc(f))

and it could then use this in the scanf engine. The fgets() and
fread() functions might look directly at f->_readcount:

int fgets(char *buf, size_t bufsize, FILE *stream) {
...
p = memchr(f->_readptr, '\n', min(f->_readsize, room_in_user_buffer));
if (p != NULL) {
/*
* Found entire input line in current buffer. Do a quick
* copy-and-take.
*/
line_len = p - f->_readptr; /* length of the line */
memcpy(buf, f->_readptr, line_len); /* copy it */
f->_readptr += line_len; /* and take it out */
f->_readsize -= line_len; /* of the stdio buffer */
} else {
/*
* Found only part of line in current buffer, or buffer
* is empty. Do whatever is required to copy partial
* line (if any) and read more input, in a loop as needed.
*/
...
}
...
}

At some point, though, these all call fgetc() (or the underlying
code that implements fgetc()) to refill the stdio buffer. It is
this code that handles "read from underlying file or device"
requests, and it is this "read from underlying file or device"
request that encounters the kinds of failures that set the end-of-file
and/or error indicators.)
 
N

nicolas.sitbon

OK OK, everybody seems to be ok to say that all I/O functions can
potentially set/clear the end-of-file indicator, but nobody give me
normative reference, and the author says that nothing in the C99 says
that all I/O functions can set/clear end-of-file indicator!!!
 
S

santosh

Eric said:
Unless the post hasn't reached my news server yet, nobody has
claimed that all I/O functions can set or clear the end-of-file
indicator. putc(), for example, cannot. Nor can ftell(), nor
setvbuf(), nor feof(), nor a bunch of others.

To quote vippstar:

All functions that perform IO operations. (ie even perror() can set
the 'error' indicator for stderr if an error occurs at writing)

A bit of an overstatement, but this happens in ordinary speech. We can't
all expect be like Keith!

<snip>
 
N

nicolas.sitbon

     The normative reference is section 7.19 of the Standard.
I looked at this section, but I didn't find anything saying clearly
that all IO input functions set/clear the end-of-file indicator!
 
S

santosh

I looked at this section, but I didn't find anything saying clearly
that all IO input functions set/clear the end-of-file indicator!

Hasn't it been made clear to you by now that only one poster has said
that all functions that perform an I/O operation set these flags, and
that he was overstating his case, as has been explained more than once?
 
N

nicolas.sitbon

Hasn't it been made clear to you by now that only one poster has said
that all functions that perform an I/O operation set these flags, and
that he was overstating his case, as has been explained more than once?

read what I said : all IO INPUT functions
 
S

santosh

read what I said : all IO INPUT functions

You have already been told that all input in C is done as if it is
composed of one or more calls to fgetc, and fgetc can most certainly
set the end-of-file indicator, and it's implied that other input
functions modelled on top of it, must also do so. Indeed they have no
choice but to do so. However they do have different methods of
notifying the user of such an exception. For example fgets returns a
null pointer, fread returns a short item count, scanf returns EOF etc.
In all cases you can always determine whether a particular FILE stream
is at end-of-file by calling the feof function, and whether an I/O
error has occurred during the last access by using the ferror function.
 
J

jameskuyper

I looked at this section, but I didn't find anything saying clearly
that all IO input functions set/clear the end-of-file indicator!

It doesn't explain it in those terms. You have to follow several
intermediate steps.

7.19.7.1p3 says that fgetc() sets the end-of-file indicator.
7.24.3.1p3 says the same for fgetwc(). All wide character input
functions have their behavior defined in terms of successive calls to
fgetwc(), and all byte input functions have their behavior defined in
terms of repeated calls to fgetc() (7.19.3p11). All of the input
functions are defined as either wide character input functions or byte
input functions (7.19.1p3) . Those functions don't have to actually
call fgetc()/fgetwc(), but must produce the same behavior as if they
called fgetc()/fgetwc(), which means that they must set the end-of-
file indicator, when appropriate.
 
N

nicolas.sitbon

You have already been told that all input in C is done as if it is
composed of one or more calls to fgetc, and fgetc can most certainly
set the end-of-file indicator, and it's implied that other input
functions modelled on top of it, must also do so. Indeed they have no
choice but to do so. However they do have different methods of
notifying the user of such an exception. For example fgets returns a
null pointer, fread returns a short item count, scanf returns EOF etc.
In all cases you can always determine whether a particular FILE stream
is at end-of-file by calling the feof function, and whether an I/O
error has occurred during the last access by using the ferror function.

sorry but, one more time, you don't answer me : can you say precisely,
where in the normative reference it is write that all IO INPUT
functions clear/set the end-of-file indicator cause if I write to the
author without any proof...
 
S

santosh

Eric said:
The O.P. asked about the end-of-file indicator. The end-of-file
indicator and the error indicator are separate indicators, and are
set and cleared under different circumstances.

You're right. Apologies to vippstar for misquoting him.
 
N

nicolas.sitbon

     Is it possible that you have confused the end-of-file
indicator with the error indicator?  They are not the same.

In fact, the author says that except the functions I mentioned above,
all other are not guaranteed to set the end-of-file OR error
indicator, and he says that other functions are not portable if used
in this way. For french programmers who want to verify my saying, the
book is "méthodologie de la programmation en C, norme C99, API POSIX"
de Achille Braquelaire.
 
J

jameskuyper

Eric Sosman wrote:
....
statement about all input functions. (Indeed, the Standard never
defines "input functions" as such, although it does define some
close relatives.)

If we take the commonsense view that "input functions" are the
"wide character input functions" (7.19.1p5) ...

Which starts out saying "The input/output functions are given the
following collective terms"
... plus fgetc, fgets, fread,
fscanf, getc, getchar, gets, scanf, vfscanf, and vscanf,

All of which fall into the category defined by 7.19.1p5 as "byte input/
output functions".

The standard may fail to distinguish between byte input and byte
output functions, but is anyone seriously in doubt as to which of the
byte input/output functions are input functions, and which ones are
output functions?
... I believe
that the description of each says it can set the end-of-file
indicator. (I haven't checked, but you're welcome to -- and

I have. The ones that process more than one character at a time don't
say so directly. You have to invoke 7.19.3p11 to determine that they
are also required to set it.
 
N

nicolas.sitbon

     Pardon me; I overlooked the insertion of the word "input" in
your restatement of the question.  Yes, the Standard says that all
input functions can set the end-of-file indicator, but it says so
in the descriptions of the individual functions, not as a blanket
statement about all input functions.  (Indeed, the Standard never
defines "input functions" as such, although it does define some
close relatives.)

     If we take the commonsense view that "input functions" are the
"wide character input functions" (7.19.1p5) plus fgetc, fgets, fread,
fscanf, getc, getchar, gets, scanf, vfscanf, and vscanf, I believe
that the description of each says it can set the end-of-file
indicator.  (I haven't checked, but you're welcome to -- and
maybe to file a Defect Report if any of them forgets to!)  You can
also search the function descriptions for those that clear or can
clear the end-of-file indicator; it would be somewhat clumsier to
make a blanket statement about the latter category.

I checked and for example, the fscanf function, nothing says that it
sets the end-of-file indicator except perhaps this example :

#include <stdio.h>
/* ... */
int count; float quant; char units[21], item[21];
do {
count = fscanf(stdin, "%f%20s of %20s", &quant, units, item);
fscanf(stdin,"%*[^\n]");
} while (!feof(stdin) && !ferror(stdin));
 
B

Barry Schwarz

I looked at this section, but I didn't find anything saying clearly
that all IO input functions set/clear the end-of-file indicator!

Since it is obviously false, you shouldn't. Read 7.19.3-11 followed
by 7.19.7.1-3 to learn when it is set. You should then be able to
find on your own when it is cleared.
 
N

nicolas.sitbon

Eric Sosman wrote:
I have. The ones that process more than one character at a time don't
say so directly. You have to invoke 7.19.3p11 to determine that they
are also required to set it.

11 The wide character input functions read multibyte characters from
the stream and convert
them to wide characters as if they were read by successive calls to
the fgetwc function.
Each conversion occurs as if by a call to the mbrtowc function,
with the conversion state
described by the stream’s own mbstate_t object. The byte input
functions read
characters from the stream as if by successive calls to the fgetc
function.


Many thanks to everybody, this time it's clear for me.
 
H

Harald van Dijk

I checked and for example, the fscanf function, nothing says that it
sets the end-of-file indicator

Okay, maybe an example is clearer for you.

7.19.1p5 (Input/output <stdio.h>; Introduction)
"The byte input/output functions [...]: [...], fscanf, [...]"

7.19.3p11 (Files)
"The byte input functions read characters from the stream as if by
successive calls to the fgetc function."

7.19.7.1p3 (The fgetc function)
"If [...] the stream is at end-of-file, the end-of-file indicator for the
stream is set [...]"

Yes, it doesn't explicitly say that fscanf sets the end-of-file indicator.
But a conforming implementation where fscanf *doesn't* set the end-of-file
indicator cannot exist; it would have to break one of these three
requirements. Either it doesn't classify fscanf as a byte input function,
or it doesn't make byte input functions read input as if by successive
calls to fgetc, or it doesn't make fgetc set the end-of-file indicator.
 
F

Flash Gordon

Malcolm McLean wrote, On 04/08/08 19:27:
The book is wrong, at least to all intents and purposes. EOF will be
returned after the contents of the file have been exhausted by any of
the read functions. feof() returns true after the first read to return EOF.

The above is at least misleading. EOF is a macro which evaluates to an
integer constant. Since some of the input functions return pointers you
are obviously wrong about all of the input functions being able to
return its value. Also for those which can return EOF they can do so
because of an error, and if it is an error causing the routine to return
EOF then feof() will not return true but ferror() will.
I think what he is thinking is that if a call to a function like
fscanf() doesn't match the input format than you'll get a partial read -
the function will return the number of arguments successfully converted
- and EOF may not be set, even if you are very close to the end of the
file and have no complete records left.

Well, that appears to not be what the OP's book was referring to, but it
is true.
 

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,982
Messages
2,570,185
Members
46,738
Latest member
JinaMacvit

Latest Threads

Top