How to use EOF to run through a text file in C?
How you detect EOF depends on what you're using to read the stream:
function result on EOF or error
-------- ----------------------
fgets() NULL
fscanf() number of succesful conversions
less than expected
fgetc() EOF
fread() number of elements read
less than expected
Check the result of the input call for the appropriate condition above, then call feof()
to determine if the result was due to hitting EOF or some other error.
Using fgets()
:
char buffer[BUFFER_SIZE];
while (fgets(buffer, sizeof buffer, stream) != NULL)
{
// process buffer
}
if (feof(stream))
{
// hit end of file
}
else
{
// some other error interrupted the read
}
Using fscanf()
:
char buffer[BUFFER_SIZE];
while (fscanf(stream, "%s", buffer) == 1) // expect 1 successful conversion
{
// process buffer
}
if (feof(stream))
{
// hit end of file
}
else
{
// some other error interrupted the read
}
Using fgetc()
:
int c;
while ((c = fgetc(stream)) != EOF)
{
// process c
}
if (feof(stream))
{
// hit end of file
}
else
{
// some other error interrupted the read
}
Using fread()
:
char buffer[BUFFER_SIZE];
while (fread(buffer, sizeof buffer, 1, stream) == 1) // expecting 1
// element of size
// BUFFER_SIZE
{
// process buffer
}
if (feof(stream))
{
// hit end of file
}
else
{
// some other error interrupted read
}
Note that the form is the same for all of them: check the result of the read operation; if it failed, then check for EOF. You'll see a lot of examples like:
while(!feof(stream))
{
fscanf(stream, "%s", buffer);
...
}
This form doesn't work the way people think it does, because feof()
won't return true until after you've attempted to read past the end of the file. As a result, the loop executes one time too many, which may or may not cause you some grief.
One possible C loop would be:
#include <stdio.h>
int main()
{
int c;
while ((c = getchar()) != EOF)
{
/*
** Do something with c, such as check against '\n'
** and increment a line counter.
*/
}
}
For now, I would ignore feof
and similar functions. Exprience shows that it is far too easy to call it at the wrong time and process something twice in the belief that eof hasn't yet been reached.
Pitfall to avoid: using char
for the type of c. getchar
returns the next character cast to an unsigned char
and then to an int
. This means that on most [sane] platforms the value of EOF
and valid "char
" values in c
don't overlap so you won't ever accidentally detect EOF
for a 'normal' char
.